题意:求无向图的严格次小生成树
思路:综合前两篇文章
http://www.cnblogs.com/myoi/archive/2012/05/13/2498184.html
http://www.cnblogs.com/myoi/archive/2012/05/14/2500371.html
1 //严格 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 #include<cstdio> 6 #include<vector> 7 #include<algorithm> 8 using namespace std; 9 #define MAXM 300010 10 #define MAXN 100010 11 #define INF 987654321 12 long long n,m,top=0; 13 struct Edge 14 { 15 long long x,y,w; 16 }; 17 struct node 18 { 19 long long num,weight,id; 20 node *next; 21 }; 22 pair<long long,long long> max_edge[MAXN]; 23 pair<long long,long long> ans[MAXM]; 24 vector<pair<long long,long long> > query[2*MAXM]; 25 vector<long long> que[MAXM]; 26 bool used[MAXM],use[MAXN]; 27 node *graph[MAXN]; 28 node memo[2*MAXM]; 29 Edge edge[MAXM]; 30 long long f[MAXN],father[MAXN],root; 31 long long Ans=0,minn=INF; 32 void add(long long x,long long y,long long w,long long id) 33 { 34 node *p=&memo[top++]; 35 p->num=y; p->weight=w; p->id=id; p->next=graph[x]; graph[x]=p; 36 p=&memo[top++]; 37 p->num=x; p->weight=w; p->id=id; p->next=graph[y]; graph[y]=p; 38 } 39 40 long long find(long long x) 41 { 42 if(f[x]==-1) return x; 43 long long root=find(f[x]); 44 if(max_edge[x].first<max_edge[f[x]].first) 45 { 46 long long temp1=max_edge[f[x]].first; 47 long long temp2=max(max_edge[x].first,max_edge[f[x]].second); 48 max_edge[x]=make_pair(temp1,temp2); 49 } 50 else if(max_edge[x].first==max_edge[f[x]].first) 51 { 52 long long temp1=max_edge[f[x]].first; 53 long long temp2=max(max_edge[x].second,max_edge[f[x]].second); 54 max_edge[x]=make_pair(temp1,temp2); 55 } 56 else 57 { 58 long long temp1=max_edge[x].first; 59 long long temp2=max(max_edge[f[x]].first,max_edge[x].second); 60 max_edge[x]=make_pair(temp1,temp2); 61 } 62 f[x]=root; 63 return root; 64 } 65 void merge(long long x,long long y) 66 { 67 long long fx=find(x),fy=find(y); 68 if(fx!=fy) 69 f[fx]=fy; 70 } 71 72 73 bool cmp(const Edge &x,const Edge &y) 74 { 75 return x.w<y.w; 76 } 77 void Kruskal() 78 { 79 long long i,u,v,j; 80 for(i=1;i<=m;i++) 81 { 82 u=edge[i].x; v=edge[i].y; 83 if(find(u)==find(v)) continue; 84 add(edge[i].x,edge[i].y,edge[i].w,i); 85 Ans+=edge[i].w; 86 root=edge[i].x; 87 used[i]=1; 88 merge(u,v); 89 } 90 } 91 void dfs(long long u) 92 { 93 max_edge[u].first=max_edge[u].second=-INF; 94 for(node *p=graph[u];p;p=p->next) 95 if(p->num!=father[u]) 96 { 97 father[p->num]=u; 98 dfs(p->num); 99 max_edge[p->num].first=p->weight; 100 max_edge[p->num].second=-INF; 101 merge(p->num,u); 102 } 103 use[u]=1; 104 vector<pair<long long,long long> >:: iterator i; 105 long long j; 106 for(i=query[u].begin();i!=query[u].end();i++) 107 if(use[i->first]) 108 que[find(i->first)].push_back(i->second); 109 for(j=0;j<que[u].size();j++) 110 { 111 find(edge[que[u][j]].x); find(edge[que[u][j]].y); 112 if(max_edge[edge[que[u][j]].x].first<max_edge[edge[que[u][j]].y].first) 113 { 114 ans[que[u][j]].first=max_edge[edge[que[u][j]].y].first; 115 ans[que[u][j]].second=max(max_edge[edge[que[u][j]].x].first,max_edge[edge[que[u][j]].y].second); 116 } 117 else if(max_edge[edge[que[u][j]].x].first==max_edge[edge[que[u][j]].y].first) 118 { 119 ans[que[u][j]].first=max_edge[edge[que[u][j]].y].first; 120 ans[que[u][j]].second=max(max_edge[edge[que[u][j]].x].second,max_edge[edge[que[u][j]].y].second); 121 } 122 else 123 { 124 ans[que[u][j]].first=max_edge[edge[que[u][j]].x].first; 125 ans[que[u][j]].second=max(max_edge[edge[que[u][j]].y].first,max_edge[edge[que[u][j]].x].second); 126 } 127 } 128 } 129 130 void solve() 131 { 132 memset(use,0,sizeof(use)); 133 memset(f,0xff,sizeof(f)); 134 long long i; 135 for(i=1;i<=m;i++) 136 if(!used[i]) 137 { 138 query[edge[i].x].push_back(make_pair(edge[i].y,i)); 139 query[edge[i].y].push_back(make_pair(edge[i].x,i)); 140 } 141 142 father[root]=0; 143 dfs(root); 144 for(i=1;i<=m;i++) 145 if(!used[i]) 146 { 147 if(ans[i].first==edge[i].w) 148 minn=min(edge[i].w-ans[i].second,minn); 149 else 150 minn=min(edge[i].w-ans[i].first,minn); 151 } 152 printf("%lld\n",Ans+minn); 153 } 154 155 156 int main() 157 { 158 memset(used,0,sizeof(used)); 159 memset(graph,0,sizeof(graph)); 160 memset(f,0xff,sizeof(f)); 161 scanf("%lld%lld",&n,&m); 162 long long i; 163 Ans=0; 164 for(i=1;i<=m;i++) 165 scanf("%lld%lld%lld",&edge[i].x,&edge[i].y,&edge[i].w); 166 sort(edge+1,edge+m+1,cmp); 167 Kruskal(); 168 solve(); 169 return 0; 170 }