Question address: zoj 3348
It is still a Network Flow Problem of a competition, but this question cannot be used to create a map in the previous competition. In 5000 games, it will obviously time out, so we need to change the idea of creating a picture. This is the last classic competition question.
The previous victory-or-Defeat transition aims to build a point for the competition and control the relationship between the two sides through the flow of the two sides of the competition, the graph creation method here is more clever (worship the great guy who came up with this method ...), Assume that one of them wins, and use MP [a] [B] to represent the number of times a wins B, and connect a and B, the weight is MP [a] [B]. In this case, the previous assumption is just a hypothesis, because here, if the traffic of A is routed to B, it means that the result of a's victory is B, which is equivalent to B's victory. This is the answer to the question, but I personally understand that the game is converted to an edge (the last is a point) Here, which connects the two sides of the game, then the traffic on this side can be added from the source point through a certain side. Finally, we can see from which endpoint flows to the sink point is equivalent to which side to win. This is my personal understanding.
The method of creating a graph is to build a Source Vertex and a sink vertex. Each person is connected to the Source Vertex, and the weight is the number of venues that this person will win, the weight value is-1 of the integral difference between the value and the DD, which is obviously used to ensure that the integral value does not exceed the value of the DD, and then connects the points using the directed edge. Determine whether the maximum stream is full. For everyone's conversion, I directly use map ing, which is more convenient.
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[200], source, sink, nv, cnt;int cur[200], num[200], d[200], pre[200], q[200], w[200], mp[200][200];struct node{ int u, v, cap, next;} edge[1000000];void add(int u, int v, int cap){ edge[cnt].v=v; edge[cnt].cap=cap; edge[cnt].next=head[u]; head[u]=cnt++; edge[cnt].v=u; edge[cnt].cap=0; edge[cnt].next=head[v]; head[v]=cnt++;}void bfs(){ memset(num,0,sizeof(num)); memset(d,-1,sizeof(d)); int f1=0, f2=0, i; d[sink]=0; num[0]=1; q[f1++]=sink; while(f1>=f2) { int u=q[f2++]; for(i=head[u]; i!=-1; i=edge[i].next) { int v=edge[i].v; if(d[v]==-1) { d[v]=d[u]+1; num[d[v]]++; q[f1++]=v; } } }}int isap(){ memcpy(cur,head,sizeof(cur)); bfs(); int flow=0, u=pre[source]=source, i; while(d[source]<nv) { if(u==sink) { int f=INF,pos; for(i=source; i!=sink; i=edge[cur[i]].v) { if(f>edge[cur[i]].cap) { f=edge[cur[i]].cap; pos=i; } } for(i=source; i!=sink; i=edge[cur[i]].v) { edge[cur[i]].cap-=f; edge[cur[i]^1].cap+=f; } flow+=f; u=pos; } for(i=cur[u]; i!=-1; i=edge[i].next) { if(d[edge[i].v]+1==d[u]&&edge[i].cap) break; } if(i!=-1) { cur[u]=i; pre[edge[i].v]=u; u=edge[i].v; } else { if(--num[d[u]]==0) break; int mind=nv; for(i=head[u]; i!=-1; i=edge[i].next) { if(mind>d[edge[i].v]&&edge[i].cap) { mind=d[edge[i].v]; cur[u]=i; } } d[u]=mind+1; num[d[u]]++; u=pre[u]; } } return flow;}int main(){ int n, m, p, i, j, z; char s1[20], s2[20], s3[20]; map<string,int>Q; while(scanf("%d%d",&n,&m)!=EOF) { memset(w,0,sizeof(w)); memset(head,-1,sizeof(head)); cnt=0; z=1; Q.clear(); char s4[20]="DD"; Q[s4]=1; for(i=0; i<m; i++) { scanf("%s%s%s",s1,s2,s3); if(!Q[s1]) Q[s1]=++z; if(!Q[s2]) Q[s2]=++z; if(strcmp(s3,"win")==0) { w[Q[s1]]++; } else { w[Q[s2]]++; } } scanf("%d",&p); memset(mp,0,sizeof(mp)); for(i=0; i<p; i++) { scanf("%s%s",s1,s2); if(!Q[s1]) Q[s1]=++z; if(!Q[s2]) Q[s2]=++z; if(Q[s1]==1||Q[s2]==1) { w[1]++; } else { mp[Q[s1]][Q[s2]]++; w[Q[s1]]++; } } int sum=0; for(i=2;i<=z;i++) sum+=w[i]; source=0; sink=z; nv=sink+1; for(i=2; i<=z; i++) { add(source,i-1,w[i]); add(i-1,sink,w[1]-1); for(j=2; j<=z; j++) { add(i-1,j-1,mp[i][j]); } } int x=isap(); //printf("%d\n",x); if(x==sum) printf("Yes\n"); else printf("No\n"); } return 0;}
Zoj 3348 schedule (map application + largest stream of network streams) (upgraded version of competition issues)