Question connection
I started to learn about the network stream. I did not know how to create this picture when I started this question.
It is very important to create a network flow graph. After the graph is created, the problem is solved. It is indeed difficult to create a graph.
Click Open Link
Take a look at this sketch:
According to the actual meaning: it should be the graph on the left (a network with multiple source nodes and multiple sink points), which can be converted into a single source node and a single source sink point. The method is to add a super source node and a super sink point. S and nodes.
Ek algorithm: (391 ms)
# Include <cstdio> # include <cstring> # include <queue> # define INF 0x3fusing namespace STD; const int n = 375; int CAP [N] [N], f [N] [N], W [51] [8]; // cap indicates the capacity, and F indicates the reserved traffic. Int pre [N], REC [N]; int n, m, R, ans; bool BFS () // search for augmented paths {int I, J; queue <int> q; memset (REC, 0, sizeof (REC); Pre [0] =-1; REC [0] = inf; q. push (0); While (! Q. empty () {I = Q. front (); q. pop (); For (j = 1; j <= r; j ++) {If (Cap [I] [J]> F [I] [J] &! REC [J]) {rec [J] = rec [I]; If (Cap [I] [J]-f [I] [J] <rec [J]) REC [J] = CAP [I] [J]-f [I] [J]; Pre [J] = I; q. push (j); If (j = r) return true ;}}return false;} void EK () {While (BFS ()) {// when no augmented path is found, the current network stream is the largest. For (INT I = r; I! = 0; I = pre [I]) {f [pre [I] [I] + = rec [R]; // modify the traffic f [I] [pre [I] =-f [pre [I] [I]; // modify the direction} ans + = rec [R]; // only the value of the inbound vertex is concerned.} Int main () {int I, J, K, deadline [51], sum, D, T; scanf ("% d", & T ); while (t --) {scanf ("% d", & N); memset (F, 0, sizeof (f); memset (Cap, 0, sizeof (CAP); M =-1, sum = 0; for (I = 1; I <= N; I ++) {for (j = 1; j <= 7; j ++) scanf ("% d", & W [I] [J]); scanf ("% d", & D, & deadline [I]); CAP [0] [I] = D; If (deadline [I]> m) M = deadline [I]; sum + = D ;} R = N + M * 7 + 1; // super settlement point. For (I = 1; I <= N; I ++) for (j = 1; j <= deadline [I]; j ++) {for (int K = 1; k <= 7; k ++) {If (W [I] [k]) {CAP [I] [n + (J-1) * 7 + k] = 1; // film and date CAP [n + (J-1) * 7 + k] [r] = 1; // sink point corresponding to daily date }}ans = 0; Ek (); If (ANS = sum) puts ("yes"); else puts ("no ");} return 0 ;}
Dinic algorithm: (47 Ms)
#include<cstdio>#include<queue>#include<cstring>#define INF 0x3f#define min(a,b) a<b?a:busing namespace std;const int N=372;int rec[N][10],cap[N][N],dis[N];int s,t,n;void set_graph(){for(int i=1;i<=n;i++){cap[0][i+350]=rec[i][8];for(int j=1;j<=7;j++){if(rec[i][j]){for(int k=0;k<rec[i][9];k++){cap[i+350][j+k*7]=1;}}}}for(int i=1;i<=350;i++) cap[i][371]=1;}bool BFS(){int i;queue<int>Q;memset(dis,-1,sizeof(dis));dis[t]=0;Q.push(t);while(!Q.empty()){ i=Q.front();Q.pop();for(int k=0;k<N;++k){if(dis[k]==-1&&cap[k][i]){dis[k]=dis[i]+1;Q.push(k);}}if(i==s) return true;}return false;}int DFS(int cur,int h){if(cur==t) return h;int tmp=h,t;for(int i=0;i<N&&tmp;i++){if((dis[i]+1==dis[cur])&& cap[cur][i]){t=DFS(i,min(cap[cur][i],tmp));cap[cur][i]-=t;cap[i][cur]+=t;tmp-=t;}}return h-tmp;}int dinic(){ intmaxflow=0;while(BFS()){maxflow+=DFS(s,INF);}return maxflow;}int main(){int sum,T;scanf("%d",&T);while(T--){scanf("%d",&n);sum=0,s=0,t=371;memset(cap,0,sizeof(cap));for(int i=1;i<=n;i++){for(int j=1;j<=9;j++)scanf("%d",&rec[i][j]);sum+=rec[i][8];}set_graph();if(dinic()==sum) puts("Yes");else puts("No");}return 0;}