標籤:class blog code ext 2014 string
將星期拆點,合格連邊,最後統計匯點流量是否滿就行了,注意結點編號。
#include<cstdio>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>#include<set>#include<map>#include<queue>#include<vector>#include<string>#define eps 1e-12#define INF 0x7fffffff#define maxn 1000using namespace std;int n,m;int en;int st,ed;//源點和匯點int dis[maxn] ;//dis[i],表示 到 原點 s 的 層數int que[999999];int can[55][11];struct edge{int to,c,next;};edge e[999999];int head[maxn];void add(int a,int b,int c){e[en].to=b;e[en].c=c;e[en].next=head[a];head[a]=en++;e[en].to=a;e[en].c=0;e[en].next=head[b];head[b]=en++;}int bfs(){ memset(dis,-1,sizeof(dis)); dis[st]=0; int front=0,rear=0; que[rear++]=st; while(front<rear) { int j=que[front++]; for(int k=head[j];k!=-1;k=e[k].next) { int i=e[k].to;if(dis[i]==-1&&e[k].c) { dis[i] = dis[j]+ 1 ; que[rear++]=i; if(i==ed) return true; } } } return false;}int dfs(int x,int mx){ int i,a; if(x==ed) return mx ; int ret=0; for(int k=head[x];k!=-1&&ret<mx;k=e[k].next) { if(e[k].c&&dis[e[k].to]==dis[x]+1) { int dd=dfs(e[k].to,min(e[k].c,mx-ret)); e[k].c-=dd; e[k^1].c+=dd; ret+=dd; } } if(!ret) dis[x]=-1; return ret;}void init(){ en=0;st=0; //源 ed=20+50*7+100; //匯memset(head,-1,sizeof(head));}void build(){ for(int i=1;i<=n;i++) add(i,ed,can[i][8]); for(int i=n+1;i<=n+350;i++) add(st,i,1); for(int i=1;i<=n;i++) { for(int j=0,id=n+1;j<can[i][9];j++) //第幾周 { for(int t=1;t<=7;t++,id++) { if(can[i][t]) add(id,i,1); } } }}int dinic(){ int tmp=0; int maxflow=0; while(bfs()) { while(tmp=dfs(st,INF)) maxflow+=tmp; } return maxflow;}int main(){ int cas; int ans; scanf("%d",&cas); while(cas--) { ans=0; scanf("%d",&n); for(int i=1;i<=n;i++) { for(int j=1;j<=9;j++) { scanf("%d",&can[i][j]); } ans+=can[i][8]; } init(); build(); // cout<<dinic()<<endl; printf("%s\n",dinic()==ans?"Yes":"No"); }}