【题目大意】
共T组数据,对于每组数据,给你一个n个点,m条边的图,设图的最小生成树为MST,次小生成树为ans,若MST=ans,输出Not Unique!,否则输出MST
【题解】
很明确,先求MST再求ans。
关于求次小生成树,我打算写一个总结,先留个坑。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cmath> 6 #include<ctime> 7 #include<algorithm> 8 using namespace std; 9 const int INF=~0u>>2;//正无穷 10 struct node{int x,y,v;}E[100010]; 11 struct Node{int y,next,v;}e[200010]; 12 int T,n,m,len,mst,ans(INF),Link[110],f[110],vis[110],map[110][110],flag[110][110],dp[110][110]; 13 inline int read() 14 { 15 int x=0,f=1; char ch=getchar(); 16 while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();} 17 while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} 18 return x*f; 19 } 20 void insert(int x,int y,int v) {e[++len].next=Link[x];Link[x]=len;e[len].y=y;e[len].v=v;} 21 int find(int x) {return f[x]==x?x:f[x]=find(f[x]);} 22 bool cmp(node a,node b) {return a.v<b.v;} 23 void Kruskal() 24 { 25 sort(E+1,E+m+1,cmp); 26 for(int i=1;i<=m;i++) 27 { 28 int x=find(E[i].x),y=find(E[i].y); 29 if(x!=y) 30 { 31 f[x]=y; 32 mst+=E[i].v; 33 flag[E[i].x][E[i].y]=flag[E[i].y][E[i].x]=1; 34 } 35 } 36 for(int i=1;i<=n;i++) 37 for(int j=i+1;j<=n;j++) 38 if(flag[i][j]) {insert(i,j,map[i][j]); insert(j,i,map[j][i]);} 39 } 40 void dfs(int st,int x,int v) 41 { 42 vis[x]=1; 43 dp[st][x]=v; 44 for(int i=Link[x];i;i=e[i].next) 45 if(!vis[e[i].y]) dfs(st,e[i].y,max(dp[st][x],e[i].v)); 46 } 47 void pre() 48 { 49 memset(Link,0,sizeof(Link)); 50 memset(flag,0,sizeof(flag)); 51 memset(dp,0,sizeof(dp)); 52 len=mst=0; ans=INF; 53 for(int i=1;i<=n;i++) f[i]=i; 54 for(int i=1;i<=n;i++) 55 for(int j=1;j<=n;j++) 56 map[i][j]=(i==j?0:INF); 57 } 58 int main() 59 { 60 freopen("cin.in","r",stdin); 61 freopen("cout.out","w",stdout); 62 T=read(); 63 while(T--) 64 { 65 n=read(); m=read(); 66 pre(); 67 for(int i=1;i<=m;i++) 68 { 69 int x=read(),y=read(),v=read(); 70 map[x][y]=map[y][x]=v; 71 E[i].x=x; E[i].y=y; E[i].v=v; 72 } 73 Kruskal(); 74 for(int i=1;i<=n;i++) {memset(vis,0,sizeof(vis)); dfs(i,i,0);} 75 for(int i=1;i<=n;i++) 76 for(int j=i+1;j<=n;j++) 77 if(!flag[i][j]&&map[i][j]!=INF) ans=min(ans,mst+map[i][j]-dp[i][j]); 78 if(ans==mst) printf("Not Unique! "); 79 else printf("%d ",mst); 80 } 81 return 0; 82 }