hdu2433(最短路径树)

来源:互联网 发布:游戏原画 培训 知乎 编辑:程序博客网 时间:2024/06/09 18:32

链接:点击打开链接

题意:给出一个n个点m条边的无向图,问删除每一条边后每两个点最短路的和

代码:

#include <set>#include <map>#include <queue>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const int INF=0x3f3f3f3f;int n,m;int x[3005],y[3005];int d[105],ss[105],vis[105];int s[105][105],fa[105][105],op[105][105];int bfs(int S){    int i,u,sum;    memset(d,INF,sizeof(d));    memset(vis,0,sizeof(vis));    d[S]=0,vis[S]=1;    queue<int> qu;    qu.push(S);    while(qu.size()){                           //因为边长是1,直接bfs        u=qu.front();        qu.pop();        for(i=1;i<=n;i++){            if(vis[i]==0&&op[u][i]!=0){                d[i]=d[u]+1;                vis[i]=1;                fa[S][i]=u;                     //fa[i][j]表示以i为根,j的父节点                qu.push(i);            }        }    }    sum=0;    for(i=1;i<=n;i++){;        if(d[i]>=INF)        return -1;        sum+=d[i];    }    return sum;}int main(){                                     //将每个节点作为根节点,向其他点    int i,j,ans,tmp,sig;                        //做最短路,从而形成了n颗树,树就    while(scanf("%d%d",&n,&m)!=EOF){            //叫做最短路树,所以只有修改最短路        memset(op,0,sizeof(op));                //上的边才会改变最短路的值,一共n棵        memset(s,INF,sizeof(s));                //树,每棵树n-1条边,因此复杂度为O(n*n*m)        for(i=1;i<=m;i++){            scanf("%d%d",&x[i],&y[i]);            s[x[i]][y[i]]=s[y[i]][x[i]]=1;            op[x[i]][y[i]]++;            op[y[i]][x[i]]++;        }        sig=0;        for(i=1;i<=n;i++){            ss[i]=bfs(i);            if(ss[i]==-1)            sig=1;        }        for(i=1;i<=m;i++){            ans=0;            if(sig){                            //本身就不连通的图,之后也不会连通                puts("INF");                continue;            }            op[x[i]][y[i]]--;                   //记录哪条边被删除            op[y[i]][x[i]]--;            for(j=1;j<=n;j++){                if(fa[j][x[i]]!=y[i]&&fa[j][y[i]]!=x[i])                ans+=ss[j];                else{                    tmp=bfs(j);                    if(tmp==-1){                        ans=-1;                        break;                    }                    else                    ans+=tmp;                }            }            op[x[i]][y[i]]++;            op[y[i]][x[i]]++;            if(ans==-1)            puts("INF");            else            printf("%d\n",ans);        }    }    return 0;}

原创粉丝点击