使n座城市间至少有两座不连通,又全是带权无向边,即求图的最小割,可以用Stoer-Wagner算法解决 代码:#include<iostream> using namespace std; const int inf=1<<30; const int MAX=510; int g[MAX][MAX]; int MinCut(int n) { int dis[MAX],node[MAX],vis[MAX];//dis[i]表示第i点到A的距离,node[i]表示i号节点属于哪个点 int i,j,k,prev,maxj,ans=inf,m=n; for(i=0;i<n;i++) { node[i]=i; } while(n>1) { maxj=1; for(i=0;i<n;i++) { dis[node[i]]=g[node[0]][node[i]];//初始化A(node[0])与各点的距离,即W(A,p) if(dis[node[i]]>dis[node[maxj]])//选出第二个加入A的点 maxj=i; } prev=0;//第一个加入的点是0号点 memset(vis,0,sizeof(vis)); vis[node[0]]=1; for(i=1;i<n;i++) { if(i==n-1)//A=V { ans=min(ans,dis[node[maxj]]); for(k=0;k<n;k++)//将prev和maxj两个点缩为一个点 ,prev { g[node[k]][node[prev]]=(g[node[prev]][node[k]]+=g[node[k]][node[maxj]]); } node[maxj]=node[--n];//由于进入下一个循环后,当前的不会被涉及,所以将它所代表的集合 //由maxj所在的集合 代替,正好也将maxj这个集合删除,因为已经并入prev代表的集合 } vis[node[maxj]]=1; prev=maxj; maxj=-1; for(j=1;j<n;j++)//找点加入A,同时更新W(A,p) ,因为A新加入了节点prev { if(!vis[node[j]]) { dis[node[j]]+=g[node[prev]][node[j]]; if(maxj==-1||dis[node[maxj]]<dis[node[j]]) maxj=j; } } } } return ans; } int main() { int a,b,n,m,w; while(scanf("%d",&n)!=EOF) { memset(g,0,sizeof(g)); for(a=0;a<n;a++) { for(b=0;b<n;b++) { scanf("%d",&g[a][b]); } } printf("%d/n",MinCut(n)); } return 0; }