Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
带需求的可行流问题 可以转化为最大流//但是老RE没法了! #include <iostream> using namespace std; const int MAXN = 205;//点的标号[0..MAXN-1] const int MAXM2 = 5005*2; const int INF = (1<<20); struct Edge { int st, ed; int next; int flow;//边的剩余容量 }edge[MAXM2];//残留网络 //head 链接表的头结点 int head[MAXN]; int E, src, dest; void Init(int s, int t)//先初始化,后读入图 { E = 0; src = s; dest = t; memset(head, -1, sizeof(head)); } void add_edge(int u, int v, int w)//u-->v:w { //允许任意形状的网络 edge[E].st = u; edge[E].ed = v; edge[E].flow = w; edge[E].next = head[u]; head[u] = E++; edge[E].st = v; edge[E].ed = u; edge[E].flow = 0; edge[E].next = head[v]; head[v] = E++; } //////////////////////dinic int d[MAXN],que[MAXN],stk[MAXN],edgptr[MAXN]; bool dinic_bfs() { int i, j ,rear=1; memset(d, -1, sizeof(d)); que[0] = src; d[src] = 0; for(i = 0; i < rear; i++) for(j = head[que[i]]; j != -1; j = edge[j].next) if(d[edge[j].ed] == -1 && edge[j].flow > 0) { d[edge[j].ed] = d[que[i]]+1; que[rear++] = edge[j].ed; } return d[dest] >= 0; } int dinic_dfs() { int ans = 0, top =0 ,cur, ptr, minf, i,pose; stk[top++] = src; while(top) { for(cur=stk[top-1],i = head[cur]; i != -1; i = edge[i].next) { if(d[edge[i].ed] == d[cur]+1 && edge[i].flow > 0 ) { stk[top++] = edge[i].ed; cur=edge[i].ed; edgptr[cur] = i; break; } } if(i == -1) { d[cur] = 0; //删点 --top; continue; } //update the flow if(cur == dest) { minf = INF; while(cur != src) //必须到达后才开始找minf { ptr = edgptr[cur]; if(edge[ptr].flow < minf) minf = edge[ptr].flow; cur = edge[ptr].st; } cur = dest; while(cur != src) { ptr = edgptr[cur]; edge[ptr].flow -= minf; edge[ptr^1].flow += minf; if(edge[ptr].flow == 0) pose = edge[ptr].st; cur = edge[ptr].st; } while(top > 0 && stk[top-1] != pose) top--; ans += minf; } } return ans; } int Dinic() { int ans = 0, t; while(dinic_bfs()) { t = dinic_dfs(); if(t) ans += t; else break; } return ans; } ////////////////////////////////////////////////高效ac了n多题 //dicnic后dfs(s)即可求的最小割集 int need[MAXN]; int deg[MAXN]; int main() { int t,n,m,s,f; cin>>t; while(t--) { memset(need,0,sizeof(need)); memset(deg,0,sizeof(deg)); cin>>n>>m; Init(0,n+1); while(m--) { cin>>s>>t>>f; deg[s]++;deg[t]++; if(s==t)continue; if(f==1) { need[s]--; need[t]++; } else { add_edge(s,t,1); add_edge(t,s,1); } } for(f=1;f<=n;++f)if(deg[f]%2==1)break; if(f<=n) { cout<<"impossible\n"; continue; } int needsum=0; for(f=1;f<=n;++f) { if(need[f]<0)add_edge(f,dest,-need[f]); if(need[f]>0){add_edge(src,f,need[f]);needsum+=need[f];} } int ans=Dinic(); if(ans==needsum)cout<<"possible\n"; else cout<<"impossible\n"; } return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator