179
对于两个城镇之间修好道路的,使他们的建造费用为0,然后prim
#include<iostream> #include<cstring> #include<algorithm> using namespace std; #define inf 0x7f7f7f7f int dis[200],n,m,map[200][200];bool vis[200]; void init() { memset(vis,false,sizeof(vis)); memset(map,inf,sizeof(map)); memset(dis,inf,sizeof(dis)); } int prim() { dis[1]=0;int minn,mark,i,j,ans=0; for(i=1;i<=n;i++) { minn=inf; for(j=1;j<=n;j++) { if(minn>dis[j]&&!vis[j]) { minn=dis[j];mark=j; } } vis[mark]=true;ans+=dis[mark]; for(j=1;j<=n;j++) { if(map[mark][j]<dis[j]&&!vis[j]) dis[j]=map[mark][j]; } } return ans; } int main() { int i,j,q; while(cin>>n) { init(); for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { cin>>map[i][j]; } } cin>>q; while(q--) { cin>>i>>j;map[i][j]=map[j][i]=0; } int d=prim(); cout<<d<<endl; } return 0; }
用kruskal算法时,使两点的父亲节点相同
#include<iostream> #include<cstring> #include<algorithm> using namespace std; struct node { int st,en,len; }E[2000*2000]; int f[20000],n,m,map[20000][20000]; bool cmp(node &a,node &b) { return a.len <b.len ; } int find(int x) { if(f[x]==x) return f[x]; else return f[x]=find(f[x]); } int kruskal() { int i,ans=0; for(i=0;i<m;i++) { int x=find(E[i].st),y=find(E[i].en); if(x!=y) { ans+=E[i].len ; f[x]=y; } } return ans; } int main() { int i,j,T,q,a,b; while(cin>>n) { T=0; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { cin>>map[i][j]; if(i<j) { E[T].st=i,E[T].en=j,E[T].len=map[i][j]; T++; } } f[i]=i; } m=n*(n-1)/2; cin>>q; while(q--) { cin>>a>>b; int x=find(a),y=find(b); f[x]=y;//使两点的父亲节点相同 } sort(E,E+T,cmp); int ans=kruskal(); cout<<ans<<endl; } return 0; }