KM的复杂度是不是又是迷啊。。。
跑的好快
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxv 1750 #define maxe 100050 #define inf 2000000000 using namespace std; int n,m,g[maxv],nume=1,x[maxv],y[maxv],w[maxv],p,q; int dis[maxv],anc[maxv][11],fath_e[maxv]; int map[maxv][maxv],slack[maxv],linky[maxv],lx[maxv],ly[maxv]; bool flag[maxv],visx[maxv],visy[maxv]; struct edge { int v,w,id,nxt; }e[maxe]; void addedge(int u,int v,int w,int id) { e[++nume].v=v;e[nume].w=w; e[nume].id=id;e[nume].nxt=g[u];g[u]=nume; } void dfs(int x) { for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if (v!=anc[x][0]) { anc[v][0]=x;dis[v]=dis[x]+1;fath_e[v]=e[i].id; dfs(v); } } } void get_table() { for (int e=1;e<=10;e++) for (int i=1;i<=n;i++) anc[i][e]=anc[anc[i][e-1]][e-1]; } int lca(int x,int y) { if (dis[x]<dis[y]) swap(x,y); for (int e=10;e>=0;e--) { if ((dis[anc[x][e]]>=dis[y]) && (anc[x][e])) x=anc[x][e]; } if (x==y) return x; for (int e=10;e>=0;e--) { if (anc[x][e]!=anc[y][e]) { x=anc[x][e]; y=anc[y][e]; } } return anc[x][0]; } void build(int x,int pos,int id,int val) { while (x!=pos) { map[id][fath_e[x]]=max(w[fath_e[x]]-val,0); x=anc[x][0]; } } bool hungary(int x) { visx[x]=true; for (int i=1;i<=m;i++) { if (visy[i]) continue; int t=lx[x]+ly[i]-map[x][i]; if (!t) { visy[i]=true; if ((linky[i]==-1) || (hungary(linky[i]))) { linky[i]=x; return true; } } else slack[i]=min(slack[i],t); } return false; } int KM() { for (int i=1;i<=m;i++) lx[i]=-inf,ly[i]=0,linky[i]=-1; for (int i=1;i<=m;i++) for (int j=1;j<=m;j++) lx[i]=max(lx[i],map[i][j]); for (int i=1;i<=m;i++) { for (int j=1;j<=m;j++) slack[j]=inf; for (;;) { memset(visx,false,sizeof(visx)); memset(visy,false,sizeof(visy)); if (hungary(i)) break; int mn=inf; for (int j=1;j<=m;j++) if (!visy[j]) mn=min(mn,slack[j]); for (int j=1;j<=m;j++) { if (visx[j]) lx[j]-=mn; if (visy[j]) ly[j]+=mn; else slack[j]-=mn; } } } int ret=0; for (int i=1;i<=m;i++) { if (linky[i]==-1) continue; ret+=map[linky[i]][i]; } return ret; } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) { scanf("%d%d%d",&x[i],&y[i],&w[i]); if (x[i]>y[i]) swap(x[i],y[i]); } for (int i=1;i<n;i++) { scanf("%d%d",&p,&q);if (p>q) swap(p,q); for (int j=1;j<=m;j++) { if ((x[j]==p) && (y[j]==q)) { addedge(p,q,w[j],j);addedge(q,p,w[j],j); flag[j]=true;break; } } } dfs(1);get_table(); for (int i=1;i<=m;i++) { if (flag[i]) continue; int t=lca(x[i],y[i]); build(x[i],t,i,w[i]); build(y[i],t,i,w[i]); } printf("%d\n",KM()); return 0; }