首页 > 代码库 > 图论练习们~

图论练习们~

/* hdu 1599 ( find the mincost route )  Floyed求最小环每个环一定是 由 i j k 构成假设k是环中的max 要成环 就要保证不是链(md废话) 利用Floyed的最外层循环含义 i-j最短路经过的点编号<k 那个我们在 限制i<j<k 那么f[i][j]+g[i][k]+g[k][j]一定能构成一个环 并且点数>=3 因为i j k 互不相同 */#include<iostream>#include<cstdio>#include<cstring>#define maxn 110#define inf 2000000using namespace std;int n,m,f[maxn][maxn],g[maxn][maxn],ans;void Clear(){    for(int i=0;i<=n;i++)        for(int j=0;j<=n;j++)            f[i][j]=g[i][j]=inf;    ans=inf;}int min(int x,int y){    return x<y?x:y;}void Floyed(){    for(int k=1;k<=n;k++){        for(int i=1;i<k;i++)            for(int j=i+1;j<k;j++)                ans=min(ans,f[i][j]+g[i][k]+g[k][j]);        for(int i=1;i<=n;i++)            for(int j=1;j<=n;j++)                f[i][j]=min(f[i][j],f[i][k]+f[k][j]);    }}int main(){    while(~scanf("%d%d",&n,&m)){        Clear();int u,v,t;        for(int i=1;i<=m;i++){            scanf("%d%d%d",&u,&v,&t);            f[u][v]=min(f[u][v],t);            f[v][u]=min(f[v][u],t);            g[u][v]=g[v][u]=f[u][v];        }        Floyed();        if(ans==inf)printf("It‘s impossible.\n");        else printf("%d\n",ans);    }    return 0;}
/*hdu 2807 ( The Shortest Path )  n*n判断矩阵相乘是不是等于另一矩阵比较快的矩阵比较方法 get了 */#include<iostream>#include<cstdio>#include<cstring>#define maxn 81#define inf 0x3f3f3f3fusing namespace std;int n,m,Q,A[maxn][maxn],f[maxn][maxn],B[maxn];struct node{    int c[maxn][maxn];}p[maxn];void Clear(){    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)            A[i][j]=0;    for(int i=1;i<=n;i++)        for(int j=1;j<=n;j++)            f[i][j]=inf;    }void Insert(int x,int y){    for(int i=1;i<=m;i++)B[i]=0;    for(int i=1;i<=m;i++)        for(int j=1;j<=m;j++)            B[i]+=p[x].c[i][j]*A[y][j];    int falg=0;    for(int k=1;k<=n;k++){        if(k==x||k==y)continue;        falg=0;        for(int i=1;i<=m;i++)            if(A[k][i]!=B[i]){                falg=1;break;            }        if(!falg)f[x][k]=1;    }}void Floyed(){    for(int k=1;k<=n;k++)        for(int i=1;i<=n;i++)            for(int j=1;j<=n;j++)                f[i][j]=min(f[i][j],f[i][k]+f[k][j]);}int main(){    while(1){        scanf("%d%d",&n,&m);        if(n==0&&m==0)break;        Clear();int u,v;        for(int k=1;k<=n;k++)            for(int i=1;i<=m;i++)                for(int j=1;j<=m;j++){                    scanf("%d",&p[k].c[i][j]);                    A[k][i]+=p[k].c[i][j]*j;                }        for(int i=1;i<=n;i++)            for(int j=1;j<=n;j++)                Insert(i,j);        Floyed();        scanf("%d",&Q);        while(Q--){            scanf("%d%d",&u,&v);            if(f[u][v]==inf)printf("Sorry\n");            else printf("%d\n",f[u][v]);        }    }    return 0;}
/* hdu 2224 ( The shortest path ) 不知道为啥出现在最短路分类里 我纯dp做的 */#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define maxn 210#define inf 0x3f3f3f3fusing namespace std;int n;double x[maxn],y[maxn],g[maxn][maxn],f[maxn][maxn],ans;struct point{    double x,y;}p[maxn];int cmp(const point &a,const point &b){    return a.x<b.x;}void Clear(){    for(int i=0;i<=n;i++)        for(int j=0;j<=n;j++)            f[i][j]=inf;    for(int i=0;i<=n;i++)        for(int j=0;j<=n;j++)            g[i][j]=inf;    ans=inf;}double Get(int i,int j){    return sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y));}int max(int a,int b){    return a>b?a:b;}int main(){    while(scanf("%d",&n)!=EOF){        Clear();        for(int i=1;i<=n;i++)            scanf("%lf%lf",&p[i].x,&p[i].y);        sort(p+1,p+1+n,cmp);        for(int i=1;i<=n;i++)            for(int j=i+1;j<=n;j++)                g[i][j]=g[j][i]=Get(i,j);        f[1][1]=0;        for(int i=1;i<=n;i++)            for(int j=1;j<=n;j++){                int k=max(i,j)+1;                f[i][k]=min(f[i][k],f[i][j]+g[j][k]);                f[k][j]=min(f[k][j],f[i][j]+g[i][k]);            }        for(int i=1;i<=n;i++){            ans=min(ans,f[i][n]+g[i][n]);            ans=min(ans,f[n][i]+g[n][i]);        }        printf("%.2f\n",ans);    }    return 0;    }
/*hdu  1598 ( find the most comfortable road )   再次被分类坑了...是并茶几不是最短路..枚举每组数据所用的最小的边-最大的边有点慢 不过还好并茶几飞快 */#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define maxn 1010using namespace std;int n,m,Q,fa[maxn],mx;struct node{    int u,v,t;    bool operator < (const node &a) const {        return t<a.t;    }}e[maxn];int init(){    int x=0,f=1;char s=getchar();    while(s<0||s>9){if(s==-)f=-1;s=getchar();}    while(s>=0&&s<=9){x=x*10+s-0;s=getchar();}    return x*f;}int find(int x){    if(x!=fa[x])fa[x]=find(fa[x]);    return fa[x];}int min(int x,int y){    return x<y?x:y;}int main(){    while(~scanf("%d%d",&n,&m)){        int u,v,t;        for(int i=1;i<=m;i++){            u=init();v=init();t=init();            e[i].u=u;e[i].v=v;e[i].t=t;        }        sort(e+1,e+1+m);        Q=init();        while(Q--){            u=init();v=init();mx=0x7fffffff;            for(int k=1;k<=m;k++){                for(int i=1;i<=n;i++)fa[i]=i;                for(int i=k;i<=m;i++){                    int r1=find(e[i].u);                    int r2=find(e[i].v);                    if(r1!=r2)fa[r2]=r1;                    if(find(u)==find(v)){                        mx=min(mx,e[i].t-e[k].t);break;                    }                }            }            if(mx==0x7fffffff)printf("-1\n");            else printf("%d\n",mx);        }    }    return 0;}
/*+几条边不存在桥*/#include<iostream>#include<cstdio>#include<stack>#include<cstring>#define maxn 1010using namespace std;int n,m,num,head[maxn],low[maxn],dfn[maxn],topt,f[maxn],r[maxn],sum,belong[maxn];stack<int>s;struct node{    int v,pre;}e[maxn*2];int init(){    int x=0,f=1;char s=getchar();    while(s<0||s>9){if(s==-)f=-1;s=getchar();}    while(s>=0&&s<=9){x=x*10+s-0;s=getchar();}    return x*f;}void Clear(){    num=0;topt=0;sum=0;    for(int i=0;i<=n;i++)f[i]=0;    for(int i=0;i<=n;i++)r[i]=0;    for(int i=0;i<=n;i++)low[i]=0;    for(int i=0;i<=n;i++)dfn[i]=0;    for(int i=0;i<=n;i++)head[i]=-1;    for(int i=0;i<=n;i++)belong[i]=0;    while(!s.empty())s.pop();}void Add(int from,int to){    e[num].v=to;    e[num].pre=head[from];    head[from]=num++;}void Dfs(int x,int from){    low[x]=dfn[x]=++topt;    f[x]=1;s.push(x);    for(int i=head[x];i!=-1;i=e[i].pre){        int v=e[i].v;        if(i==(from^1))continue;        if(dfn[v]==0){            Dfs(v,i);low[x]=min(low[x],low[v]);        }        else if(f[v])low[x]=min(low[x],dfn[v]);    }    if(low[x]==dfn[x]){        sum++;        while(s.top()!=x){            belong[s.top()]=sum;f[s.top()]=0;s.pop();        }        belong[s.top()]=sum;f[s.top()]=0;s.pop();    }}int main(){    while(~scanf("%d%d",&n,&m)){        Clear();int u,v;        for(int i=1;i<=m;i++){            u=init();v=init();            Add(u,v);Add(v,u);        }        for(int i=1;i<=n;i++)            if(dfn[i]==0)Dfs(i,-1);        for(int u=1;u<=n;u++)            for(int i=head[u];i!=-1;i=e[i].pre){                int v=e[i].v;                if(belong[u]!=belong[v])r[belong[u]]++;            }        int cnt=0;        for(int i=1;i<=sum;i++)            if(r[i]==1)cnt++;        printf("%d\n",(cnt+1)/2);    }    return 0;}
/*hdu 3768 ( Shopping )   SPFA+全排列*/#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#define maxn 200010using namespace std;int T,n,m,k,c[20],num,head[maxn],dis[maxn],g[20][20],f[maxn],a[20];long long ans;struct node{    int v,t,pre;}e[maxn*10];queue<int>q;int init(){    int x=0,f=1;char s=getchar();    while(s<0||s>9){if(s==-)f=-1;s=getchar();}    while(s>=0&&s<=9){x=x*10+s-0;s=getchar();}    return x*f;}void Clear(){    num=0;ans=0x7fffffff;    memset(head,0,sizeof(head));    memset(g,127/3,sizeof(g));    memset(a,0,sizeof(a));    memset(c,0,sizeof(c));}void Add(int from,int to,int dis){    num++;e[num].v=to;    e[num].t=dis;    e[num].pre=head[from];    head[from]=num;}void SPFA(int s){    memset(dis,127/3,sizeof(dis));    memset(f,0,sizeof(f));    dis[s]=0;f[s]=1;q.push(s);    while(!q.empty()){        int u=q.front();        f[u]=0;q.pop();        for(int i=head[u];i;i=e[i].pre){            int v=e[i].v;            if(dis[v]>dis[u]+e[i].t){                dis[v]=dis[u]+e[i].t;                if(f[v]==0){                    f[v]=1;q.push(v);                }            }        }    }}int main(){    T=init();    while(T--){        n=init();m=init();        Clear();int u,v,t;        for(int i=1;i<=m;i++){            u=init();v=init();t=init();            Add(u,v,t);Add(v,u,t);        }        k=init();        for(int i=1;i<=k;i++){            c[i]=init();a[i]=i;        }        SPFA(0);        for(int i=1;i<=k;i++)            g[0][i]=g[i][0]=dis[c[i]];        for(int i=1;i<=k;i++){            SPFA(c[i]);            for(int j=1;j<=k;j++)                g[i][j]=dis[c[j]];        }        do{            long long mx=0;            for(int i=1;i<=k+1;i++)                mx+=g[a[i-1]][a[i]];            ans=min(ans,mx);        }while(next_permutation(a+1,a+k+1));        cout<<ans<<endl;    }    return 0;}
/*poj 1679 次小生成树n*n算法 get了*/#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define maxn 110using namespace std;int T,n,m,num,head[maxn],fa[maxn],c[maxn*maxn],mx[maxn][maxn],mst,ans;struct node{    int u,v,t,o;    bool operator < (const node &x) const{        return t<x.t;    }}p[maxn*maxn];struct edge{    int v,t,pre,x;}e[maxn*maxn*2];void Clear(){    num=mst=0;ans=0x7fffffff;    for(int i=0;i<=n;i++)fa[i]=i;    for(int i=0;i<=n;i++)        for(int j=0;j<=n;j++)            mx[i][j]=0;    for(int i=0;i<=m;i++)c[i]=0;    for(int i=0;i<=n;i++)head[i]=0;}void Add(int from,int to,int dis,int numb){    num++;e[num].v=to;    e[num].t=dis;    e[num].x=numb;    e[num].pre=head[from];    head[from]=num;}int find(int x){    if(x!=fa[x])fa[x]=find(fa[x]);    return fa[x];}void MST(){    int tot=0;    for(int i=1;i<=m;i++){        int r1=find(p[i].u);        int r2=find(p[i].v);        if(r1!=r2){            tot++;mst+=p[i].t;            c[p[i].o]=1;fa[r2]=r1;        }        if(tot==n-1)break;    }}void Dfs(int s,int now,int from,int mxx){    mx[s][now]=mxx;    for(int i=head[now];i;i=e[i].pre){        int v=e[i].v;        if(v==from)continue;        if(c[e[i].x]==0)continue;        Dfs(s,v,now,max(mxx,e[i].t));    }}void Mx(){    for(int i=1;i<=n;i++)        Dfs(i,i,-1,0);}int main(){    scanf("%d",&T);    while(T--){        scanf("%d%d",&n,&m);        Clear();int u,v,t;        for(int i=1;i<=m;i++){            scanf("%d%d%d",&u,&v,&t);            Add(u,v,t,i);Add(v,u,t,i);            p[i].u=u;p[i].v=v;            p[i].t=t;p[i].o=i;        }        sort(p+1,p+1+m);        MST();Mx();        for(int i=1;i<=m;i++){            if(c[p[i].o])continue;            int len=mx[p[i].u][p[i].v];            ans=min(ans,mst+p[i].t-len);        }        if(ans==mst)printf("Not Unique!\n");        else printf("%d\n",mst);    }    return 0;}

 

图论练习们~