Address: hdu1853
The fee flow is amazing .. It can also be used to determine the ring... If each vertex is a part of the ring and each vertex can only be used once, the initial entry degree of each vertex is 1, which can be solved using the network stream, as long as the split point sets the traffic to 1, each point can only be used once. Each time the left side is connected to the right side, it is equivalent to a first degree on the left and an entry degree on the right. It is easy to imagine. Finally, you only need to determine whether the total traffic is N, because if the total traffic is N, it means that each point has a degree, each point has a degree, and due to the traffic limit of the split point, it fully demonstrates that the initial import of each point is 1. then it is explained that each point is in the ring. Then, the final minimum charge flow is the shortest distance.
The Code is as follows:
#include <iostream>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <math.h>#include <ctype.h>#include <queue>#include <map>#include <algorithm>using namespace std;const int INF=0x3f3f3f3f;int head[300], s, t, cnt, flow, cost;int vis[300], d[300], q[100000], cur[300];struct node{ int u, v, cap, cost, next;}edge[100000];void add(int u, int v, int cap, int cost){ edge[cnt].v=v; edge[cnt].cap=cap; edge[cnt].cost=cost; edge[cnt].next=head[u]; head[u]=cnt++; edge[cnt].v=u; edge[cnt].cap=0; edge[cnt].cost=-cost; edge[cnt].next=head[v]; head[v]=cnt++;}int spfa(){ memset(d,INF,sizeof(d)); memset(vis,0,sizeof(vis)); d[s]=0; cur[s]=-1; int f1=0 ,f2=0, i, minflow=INF; q[f1++]=s; while(f1>=f2) { int u=q[f2++]; vis[u]=0; for(i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(d[v]>d[u]+edge[i].cost&&edge[i].cap) { d[v]=d[u]+edge[i].cost; if(minflow>edge[i].cap) { minflow=edge[i].cap; } cur[v]=i; if(!vis[v]) { q[f1++]=v; vis[v]=1; } } } } if(d[t]==INF) return 0; flow+=minflow; cost+=minflow*d[t]; for(i=cur[t];i!=-1;i=cur[edge[i^1].v]) { edge[i].cap-=minflow; edge[i^1].cap+=minflow; } return 1;}int main(){ int n, m, i, a, b, c; while(scanf("%d%d",&n,&m)!=EOF) { memset(head,-1,sizeof(head)); cnt=0; s=0; t=2*n+1; flow=0; cost=0; for(i=1;i<=n;i++) { add(s,i,1,0); add(i+n,t,1,0); } while(m--) { scanf("%d%d%d",&a,&b,&c); add(a,b+n,1,c); } while(spfa()); if(flow!=n) printf("-1\n"); else printf("%d\n",cost); } return 0;}