这个故事告诉我们,二分图偏差一点点就错。
1和n+1,n和2*n难道不能看成同一个点吗啊魂淡。。。。。。。
要遵守二分图的对称美。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<queue> #define maxe 100500 #define maxv 650 #define inf 1000000007 using namespace std; struct edge { int v,f,c,nxt; }e[maxe]; int n,m,a,b,c,g[maxv],pree[maxv],prev[maxv],dis[maxv],max_flow=0,min_cost=0; int s,t,nume=1; bool vis[maxv]; queue <int> q; void addedge(int u,int v,int f,int c) { e[++nume].v=v; e[nume].f=f; e[nume].c=c; e[nume].nxt=g[u]; g[u]=nume; e[++nume].v=u; e[nume].f=0; e[nume].c=-c; e[nume].nxt=g[v]; g[v]=nume; } bool spfa() { while (!q.empty()) q.pop(); memset(prev,0,sizeof(prev)); memset(pree,0,sizeof(pree)); fill(dis+1,dis+t+1,inf); 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 ((dis[v]>dis[head]+e[i].c) && (e[i].f>0)) { dis[v]=dis[head]+e[i].c; pree[v]=i;prev[v]=head; if (vis[v]==false) {vis[v]=true;q.push(v);} } } vis[head]=false; } if (dis[t]==inf) return false; return true; } void dinic() { int now=t,dd=inf; while (now!=s) { dd=min(dd,e[pree[now]].f); now=prev[now]; } now=t;max_flow+=dd; while (now!=s) { e[pree[now]].f-=dd; e[pree[now]^1].f+=dd; now=prev[now]; } min_cost+=dis[t]*dd; } int main() { scanf("%d%d",&n,&m); s=0;t=2*n+1; for (int i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); addedge(a+n,b,1,c); } for (int i=2;i<=n-1;i++) addedge(i,i+n,1,0); addedge(s,1,inf,0);addedge(1,n+1,inf,0); addedge(n,2*n,inf,0);addedge(2*n,t,inf,0); while (spfa()) dinic(); printf("%d %d\n",max_flow,min_cost); return 0; }