Take the dock as a 0-point deal.
First, determine whether the pier can generate a minimum spanning tree
Kruskal algorithm for minimum spanning tree, if for the side of cost <0, join directly
If possible: min (minimum spanning tree (not built pier), minimum spanning tree (built pier));
If not: minimum spanning tree (build pier)
#include "stdio.h" #include "string.h" #include "algorithm" using namespace std;int father[10010];struct link{int a,b,v;} Link[110001];int Min (int a,int b) {if (a<b) return A; else return b;} int fin (int x) {if (x==father[x]) return x; Father[x]=fin (Father[x]); return father[x];} BOOL CMP (Link A,link b) {return A.V<B.V;} int Kruskal (int m) {int sum,i,fa,fb; sum=0; for (i=0;i<m;i++) {Fa=fin (LINK[I].A); Fb=fin (LINK[I].B); if (FA!=FB | | link[i].v<0) {SUM+=LINK[I].V; FATHER[FA]=FB; }} return sum;} int main () {int n,m,i,cnt,fa,fb,ans,x; scanf ("%d%d", &n,&m); for (i=0;i<=n;i++) father[i]=i; for (i=0;i<m;i++) scanf ("%d%d%d", &LINK[I].A,&LINK[I].B,&LINK[I].V); cnt=0; for (i=1;i<=n;i++) {scanf ("%d", &x); if (x!=-1) {link[m+cnt].a=0; Link[m+cnt].b=i; Link[m+cnt].v=x; cnt++; }} for (i=0;i<m;i++) {Fa=fin (LINK[I].A); Fb=fin (LINK[I].B); FATHER[FA]=FB; } for (i=2;i<=n;i++) if (Fin (1)!=fin (i)) break; if (i==n+1) {for (i=0;i<=n;i++) father[i]=i; Sort (link,link+m,cmp); Ans=kruskal (m); for (i=0;i<=n;i++) father[i]=i; Sort (link,link+m+cnt,cmp); Ans=min (Ans,kruskal (m+cnt)); printf ("%d\n", ans); } else {for (i=0;i<=n;i++) father[i]=i; Sort (link,link+m+cnt,cmp); printf ("%d\n", Kruskal (m+cnt)); } return 0;}
Blue Bridge Cup previous questions City construction minimum spanning tree