链接http://acm.tju.edu.cn/toj/showp4117.html
4117. Happy tree friends
Time Limit: 1.0 Seconds Memory Limit: 65536K
Total Runs: 164 Accepted Runs: 60
yuebai has an undirected complete graph with n vertices. He wants to know the minimum spanning tree of the graph. It's so easy, so yuebai wants to challenge himself. He will choose one edge which must be
in the spanning tree.
INPUT
There are multiple test cases.
For each test case, the first line contain an integer n.
In the next n lines,
there is an adjacency matrix M. Mij denotes
the weight of the edge i to j.
Next line contains two dinstinct integer u and v,
which denotes the edge which is from u to v with
the value Muv must
be in the spanning tree.
(2≤n≤100,0≤Mij≤100). Mij=0 if
and only if i=j.
OUTPUT
For each case, print the result.
Sample Input
3
0 2 3
1 0 4
5 10 0
2 3
Sample Output
5
Hint
The edge of the spanning tree is 2->3 and 2->1
Source: TJU
Team Selection 2015 Round B
用Kruskal做
只要把题目中要求的边先合和起来,其余按照模版来,题目说了无向,所以对于每边的长度取矩阵中的最小值(真是坑,一开始以为是最小树形图)
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std; #define N 50005
int a[105][105];
struct graph{
int x,y,wei;
}nodd[N];
int m,n,ufind[N]; int cmp(graph a1,graph a2){
return a1.wei<a2.wei;
}
int find(int x){
return ufind[x]==x? x : ufind[x]=find(ufind[x]);
}
int Kruskal(int a,int b){
int ans=0;
int i,j;
for(i=1;i<=n;i++) ufind[i]=i;
sort(nodd,nodd+m,cmp);
ufind[a]=b;
for(i=0;i<m;i++){
int x=find(nodd[i].x); int y=find(nodd[i].y);
if(x!=y){
ans+=nodd[i].wei;
ufind[x]=y;
}
}
return ans;
} int main(){
int x;
int sum;
int temp;
int a1,a2;
int i,j,k;
while(scanf("%d",&x)!=EOF){
sum=0;
temp=0;
for(i=1;i<=x;i++)
for(j=1;j<=x;j++)
scanf("%d",&a[i][j]);
m=x*(x-1)/2;
n=x;
scanf("%d %d",&a1,&a2);
sum+=a[a1][a2];
a[a2][a1]=a[a1][a2];
for(i=1;i<=x;i++)
for(j=i+1;j<=x;j++){
nodd[temp].x=i; nodd[temp].y=j; nodd[temp].wei=min(a[i][j],a[j][i]);
temp++;
}
//for(i=0;i<temp;i++) printf("%d %d %d\n",nodd[i].x,nodd[i].y,nodd[i].wei);
printf("%d\n",Kruskal(a1,a2)+sum);
}
}