有个两百多行的板子,没有注释,看着好像挺对的,先挖个坑以后填。
1 #include <bits/stdc++.h>
2 #define N 810
3 using namespace std;
4 typedef long long ll;
5 inline int read()
6 {
7 int x=0,f=1; char ch=getchar();
8 while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
9 while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
10 return x*f;
11 }
12 struct edge{int u,v,w;}mps[N][N];
13 int n,m,mat[N],pre[N],bl[N],fa[N],tim;ll totw=0;
14 int sign[N],lab[N],slacku[N],blofm[N][N],tot,mx;
15 vector <int> leaves[N];
16 int q[N],hd;
17 inline int calc_e(const edge &e)
18 {
19 return lab[e.u]+lab[e.v]-mps[e.u][e.v].w*2;
20 }
21 inline void updata(int u,int x)
22 {
23 if(!slacku[x]||calc_e(mps[u][x])<calc_e(mps[slacku[x]][x]))
24 slacku[x]=u;
25 }
26 inline void calc_slack(int x)
27 {
28 slacku[x]=0;
29 for(int i=1;i<=n;i++)
30 if(mps[i][x].w>0&&fa[i]!=x&&sign[fa[i]]==0)
31 updata(i,x);
32 }
33 inline void q_push(int x)
34 {
35 if(x<=n) q[++hd]=x;
36 else for(int i=0;i<(int)leaves[x].size();i++)
37 q_push(leaves[x][i]);
38 }
39 inline int get_lca(int x, int y)
40 {
41 if(tim=100000000)
42 memset(bl,0,sizeof bl),tim=0;
43 for(++tim;x||y;swap(x,y)) if(x)
44 {
45 if(bl[x]==tim) return x;
46 bl[x]=tim; x=fa[mat[x]];
47 if(x) x=fa[pre[x]];
48 }
49 return 0;
50 }
51 inline void set_fa(int x,int y)
52 {
53 fa[x]=y; if(x>n)
54 for(int i=0;i<(int)leaves[x].size();i++)
55 set_fa(leaves[x][i],y);
56 }
57 inline void set_mat(int x,int y)
58 {
59 mat[x]=mps[x][y].v;
60 if(x<=n) return ;
61 int xr=blofm[x][mps[x][y].u];
62 int pr=find(leaves[x].begin(),leaves[x].end(),xr)-leaves[x].begin();
63 if(pr%2==1)
64 reverse(leaves[x].begin()+1, leaves[x].end()),
65 pr=(int)leaves[x].size()-pr;
66 for(int i=0;i<pr;i++)
67 set_mat(leaves[x][i],leaves[x][i^1]);
68 set_mat(xr,y);
69 rotate(leaves[x].begin(),leaves[x].begin()+pr,leaves[x].end());
70 }
71 inline void blossom_blooms(int x)
72 {
73 for(int i=0;i<(int)leaves[x].size();i++)
74 {
75 if(leaves[x][i]>n&&!lab[leaves[x][i]])
76 blossom_blooms(leaves[x][i]);
77 else set_fa(leaves[x][i],leaves[x][i]);
78 }
79 fa[x]=0;
80 }
81 inline void blossom_make(int u,int lca,int v)
82 {
83 int x=n+1; while(x<=tot&&fa[x]) x++;
84 if(x>tot) tot++;
85 lab[x]=sign[x]=0;
86 mat[x]=mat[lca]; leaves[x].clear();
87 leaves[x].push_back(lca);
88 for(int i=u;i!=lca;i=fa[pre[fa[mat[i]]]])
89 leaves[x].push_back(i),leaves[x].push_back(fa[mat[i]]),q_push(fa[mat[i]]);
90 reverse(leaves[x].begin()+1, leaves[x].end());
91 for(int i=v;i!=lca;i=fa[pre[fa[mat[i]]]])
92 leaves[x].push_back(i),leaves[x].push_back(fa[mat[i]]),q_push(fa[mat[i]]);
93 set_fa(x,x);
94 for(int i=1;i<=tot;i++)
95 mps[x][i].w=mps[i][x].w=0, blofm[x][i]=0;
96 for(int i=0;i<(int)leaves[x].size();i++)
97 {
98 int xs=leaves[x][i];
99 for(int j=1;j<=tot;j++)
100 if(!mps[x][j].w||calc_e(mps[xs][j])<calc_e(mps[x][j]))
101 mps[x][j]=mps[xs][j],mps[j][x]=mps[j][xs];
102 for(int j=1;j<=tot;j++)
103 if(blofm[xs][j]) blofm[x][j]=xs;
104 }
105 calc_slack(x);
106 }
107 inline void link(int x,int y)
108 {
109 while(1)
110 {
111 int xx=fa[mat[x]];
112 set_mat(x,y);
113 if(!xx) return ;
114 set_mat(xx,fa[pre[xx]]);
115 x=fa[pre[xx]]; y=xx;
116 }
117 }
118 inline int deal_edge(const edge &e)
119 {
120 int u=fa[e.u],v=fa[e.v];
121 if(sign[v]==-1) //unsigned
122 {
123 pre[v]=e.u; // cause we bfs all vertices tegother,we dont' need to discuss two situation
124 sign[v]=1; sign[fa[mat[v]]]=0;
125 slacku[v]=slacku[fa[mat[v]]]=0;
126 q_push(fa[mat[v]]);
127 }
128 else if(!sign[v]) //S signed vertex
129 {
130 int lca=get_lca(u,v);
131 if(!lca)
132 {
133 link(u,v); link(v,u); //connected! new argument.
134 for(int i=n+1;i<=tot;i++)
135 if(fa[i]==i&&lab[i]==0)
136 blossom_blooms(i); // flower may not be a flower any more so we blossom blooms!
137 return 1;
138 }
139 else blossom_make(u,lca,v); // form a new flower!
140 }
141 return 0;
142 }
143 inline void blossom_bloom_1(int x)
144 {
145
146 for(int i=0;i<(int)leaves[x].size();i++)
147 set_fa(leaves[x][i],leaves[x][i]);
148 int xr=blofm[x][mps[x][pre[x]].u];
149 int pr=find(leaves[x].begin(), leaves[x].end(),xr)-leaves[x].begin();
150 if(pr%2==1)
151 reverse(leaves[x].begin()+1, leaves[x].end()),
152 pr=(int)leaves[x].size()-pr;
153 for(int i=0;i<pr;i+=2)
154 {
155 int u=leaves[x][i],v=leaves[x][i+1];
156 pre[u]=mps[v][u].u;
157 sign[u]=1; sign[v]=0;
158 slacku[u]=0; calc_slack(v); q_push(v);
159 }
160 sign[xr]=1; pre[xr]=pre[x];
161 for(int i=pr+1;i<(int)leaves[x].size();i++)
162 {
163 int u=leaves[x][i];
164 sign[u]=-1; calc_slack(u);
165 }
166 fa[x]=0;
167 }
168 inline int match()
169 {
170 for(int i=1;i<=tot;i++) slacku[i]=0,sign[i]=-1;
171 hd=0; for(int i=1;i<=tot;i++)
172 if(fa[i]==i&&!mat[i])
173 slacku[i]=pre[i]=sign[i]=0,q_push(i);
174 if(!hd) return 0;
175 while(1)
176 {
177 for(int i=1;i<=hd;i++)
178 {
179 int lx=q[i]; for(int j=1;j<=n;j++)
180 if(mps[lx][j].w>0&&fa[lx]!=fa[j])
181 {
182 if(!calc_e(mps[lx][j]))
183 {
184 if(deal_edge(mps[lx][j]))
185 return 1;
186 }
187 else if(sign[fa[j]]!=1) updata(lx,fa[j]);
188 }
189 }
190 int d=0x3fffffff;
191 for(int i=1;i<=n;i++) if(!sign[fa[i]])
192 d=min(d,lab[i]);
193 for(int i=n+1;i<=tot;i++)
194 if(fa[i]==i&&sign[i]==1)
195 d=min(lab[i]/2,d);
196 for(int i=1;i<=tot;i++) if(fa[i]==i&&slacku[i])
197 {
198 if(sign[i]==-1) d=min(calc_e(mps[slacku[i]][i]),d);
199 else if(sign[i]==0) d=min(calc_e(mps[slacku[i]][i])/2,d);
200 }
201 for(int i=1;i<=n;i++)
202 if(sign[fa[i]]==0) lab[i]-=d;
203 else if (sign[fa[i]]==1) lab[i]+=d;
204 for(int i=n+1;i<=tot;i++)
205 if(fa[i]==i)
206 {
207 if(sign[i]==0) lab[i]+=d*2;
208 else if(sign[i]==1) lab[i]-=d*2;
209 }
210 hd=0;
211 for(int i=1;i<=n;i++) if(!lab[i]) return 0; //all vetices matched,single vetices's label = 0
212 for(int i=1;i<=tot;i++)
213 if(fa[i]==i&&slacku[i]&&fa[slacku[i]]!=i&&calc_e(mps[slacku[i]][i])==0)
214 /*new edge*/ if(deal_edge(mps[slacku[i]][i])) return 1;
215 for(int i=n+1;i<=tot;i++)
216 if(fa[i]==i&&sign[i]==1&&!lab[i])
217 blossom_bloom_1(i);
218 }
219 return 0;
220 }
221 inline void solve()
222 {
223 for(int i=1;i<=n;i++) mat[i]=0;
224 tot=n; hd=totw=0;
225 for(int i=0;i<=n;i++) fa[i]=i,leaves[i].clear();
226 for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)
227 blofm[i][j]=(i==j? i:0);
228 for(int i =1;i<=n;i++) lab[i]=mx; //init label
229 while(match());
230 for(int i=1;i<=n;i++) if(mat[i]&&mat[i]<i)
231 totw+=mps[i][mat[i]].w;
232 }
233 int main()
234 {
235 n=read(); m=read();
236 for(int i=1;i<=n;i++)
237 for(int j=1;j<=n;j++)
238 mps[i][j]=(edge){i,j,0};
239 for(int i=1;i<=m;i++)
240 {
241 int u=read(), v=read(), w=read();
242 mps[u][v].w=mps[v][u].w=w; mx=max(mx,w);
243 }
244 solve(); printf("%lld\n",totw);
245 for(int i=1;i<=n;i++)
246 printf("%d ",mat[i]);
247 puts("");
248 return 0;
249 }