GH树。。。好像无向图上跑DINIC要慢一点。
反正能过就是了。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define maxe 200050 #define maxv 1050 const int inf=0x7fffffff/2; using namespace std; struct edge { int v,f,nxt; }e[maxe]; int n,m,a,b,c,g[maxv],fath[maxv],f[maxv][maxv]; int map[maxv][maxv],nume,s,t; int dis[maxv],regis[800500]; bool vis[maxv]; queue <int> q; void addedge(int u,int v,int f) { e[++nume].v=v; e[nume].f=f; e[nume].nxt=g[u]; g[u]=nume; e[++nume].v=u; e[nume].f=0; e[nume].nxt=g[v]; g[v]=nume; } void build() { nume=1;memset(g,0,sizeof(g)); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) { if (map[i][j]) addedge(i,j,map[i][j]); } } bool bfs() { while (!q.empty()) q.pop(); memset(dis,0,sizeof(dis)); memset(vis,false,sizeof(vis)); q.push(s);dis[s]=0;vis[s]=true; while (!q.empty()) { int head=q.front(); q.pop(); for (int i=g[head];i;i=e[i].nxt) { int v=e[i].v; if ((e[i].f>0) && (!vis[v])) { vis[v]=true; dis[v]=dis[head]+1; q.push(v); } } } return dis[t]>0; } int dinic(int x,int low) { if (x==t) return low; else { int ret=0; for (int i=g[x];low && i;i=e[i].nxt) { int v=e[i].v; if ((e[i].f>0) && (dis[v]==dis[x]+1)) { int dd=dinic(v,min(low,e[i].f)); ret+=dd;low-=dd; e[i].f-=dd;e[i^1].f+=dd; } } if (!ret) dis[x]=0; return ret; } } int max_flow(int x,int y) { s=x;t=y; int now=0; while (bfs()) now+=dinic(s,inf); return now; } void dfs(int now) { vis[now]=true; for (int i=g[now];i;i=e[i].nxt) { int v=e[i].v; if ((e[i].f>0) && (!vis[v])) dfs(v); } } void Gusfield() { for (int i=1;i<=n;i++) fath[i]=1; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) f[i][j]=inf; for (int i=2;i<=n;i++) { build(); int maxf=max_flow(fath[i],i); memset(vis,false,sizeof(vis)); dfs(fath[i]); for (int j=1;j<i;j++) f[i][j]=f[j][i]=min(f[j][fath[i]],maxf); for (int j=i+1;j<=n;j++) { if ((fath[i]==fath[j]) && (!vis[j])) fath[j]=i; } } } void get_ans() { int cnt=0; for (int i=1;i<=n;i++) { for (int j=1;j<=n;j++) { if (f[i][j]!=inf) regis[++cnt]=f[i][j]; } } sort(regis+1,regis+cnt+1); int ans=unique(regis+1,regis+cnt+1)-regis-1; printf("%d ",ans); } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); map[a][b]+=c;map[b][a]+=c; } Gusfield(); get_ans(); return 0; }