POJ 1698 Alice's Chance(最大流)
2014-08-29 12:26
323 查看
POJ 1698 Alice's Chance(最大流)
http://poj.org/problem?id=1698
题意:
爱丽丝要拍电影,有n部电影,规定爱丽丝每部电影在每个礼拜只有固定的几天可以拍电影,只可以拍前面w个礼拜,并且这部电影要拍d天,问爱丽丝能不能拍完所有的电影?
第一行代表有多少组数据
对于每组数据第一行代表有n部电影
接下来2到n+1行,每行代表一个电影,每行9个数,前面7个数,1代表拍,0代表不拍,第8个数代表要拍几天,第9个数代表有几个礼拜时间拍.
分析:
构图:
0号节点表源点S, 1-350号节点表示每一天(因为最多只有50周),然后350+1到350+N表示这N部电影. 351+N号节点是汇点.
源点到每部电影i有边(s, i, Di). Di表示这部电影需要拍多少天.
每天j到汇点t有边(j, t, 1).
如果电影i能在第j天拍摄,那么从i到j有边(i,j,1).
最终我们求最大流flow,看看flow是否等于所有电影需要天数的总和?
AC代码:
http://poj.org/problem?id=1698
题意:
爱丽丝要拍电影,有n部电影,规定爱丽丝每部电影在每个礼拜只有固定的几天可以拍电影,只可以拍前面w个礼拜,并且这部电影要拍d天,问爱丽丝能不能拍完所有的电影?
第一行代表有多少组数据
对于每组数据第一行代表有n部电影
接下来2到n+1行,每行代表一个电影,每行9个数,前面7个数,1代表拍,0代表不拍,第8个数代表要拍几天,第9个数代表有几个礼拜时间拍.
分析:
构图:
0号节点表源点S, 1-350号节点表示每一天(因为最多只有50周),然后350+1到350+N表示这N部电影. 351+N号节点是汇点.
源点到每部电影i有边(s, i, Di). Di表示这部电影需要拍多少天.
每天j到汇点t有边(j, t, 1).
如果电影i能在第j天拍摄,那么从i到j有边(i,j,1).
最终我们求最大流flow,看看flow是否等于所有电影需要天数的总和?
AC代码:
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> #include<vector> #define INF 1e9 using namespace std; const int maxn=400+5; struct Edge { int from,to,cap,flow; Edge(){} Edge(int f,int t,int c,int fl):from(f),to(t),cap(c),flow(fl){} }; struct Dinic { int n,m,s,t; vector<Edge> edges; vector<int> G[maxn]; bool vis[maxn]; int d[maxn]; int cur[maxn]; void init(int n,int s,int t) { this->n=n, this->s=s, this->t=t; edges.clear(); for(int i=0;i<n;i++) G[i].clear(); } void AddEdge(int from,int to,int cap) { edges.push_back( Edge(from,to,cap,0) ); edges.push_back( Edge(to,from,0,0) ); m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool BFS() { queue<int> Q; memset(vis,0,sizeof(vis)); vis[s]=true; d[s]=0; Q.push(s); while(!Q.empty()) { int x= Q.front(); Q.pop(); for(int i=0;i<G[x].size();++i) { Edge& e=edges[G[x][i]]; if(!vis[e.to] && e.cap>e.flow) { vis[e.to]=true; d[e.to]=d[x]+1; Q.push(e.to); } } } return vis[t]; } int DFS(int x,int a) { if(x==t || a==0)return a; int flow=0,f; for(int& i=cur[x];i<G[x].size();++i) { Edge& e=edges[G[x][i]]; if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0) { e.flow +=f; edges[G[x][i]^1].flow -=f; flow +=f; a-=f; if(a==0) break; } } return flow; } int max_flow() { int ans=0; while(BFS()) { memset(cur,0,sizeof(cur)); ans+=DFS(s,INF); } return ans; } }DC; int n,day_sum;//电影数,总共需要天数 int src,dst; int can[20+5][7];//can[i][j] 表示第i部电影在一周的第j+1天是否可以拍摄 int need[20+5]; int week[20+5]; int main() { int T; scanf("%d",&T); while(T--) { day_sum=0; scanf("%d",&n); src=0,dst=350+n+1; DC.init(350+n+2,src,dst); for(int i=1;i<=n;i++) { for(int j=0;j<7;j++) scanf("%d",&can[i][j]); scanf("%d%d",&need[i],&week[i]); DC.AddEdge(src,350+i,need[i]); day_sum += need[i]; } for(int i=1;i<=350;i++)//i表每一天 { DC.AddEdge(i,dst,1); for(int j=1;j<=n;j++)if(can[j][i%7]==1 && (i-1)/7<week[j]) { DC.AddEdge(j+350,i,1); } } printf("%s\n",DC.max_flow()==day_sum?"Yes":"No"); } return 0; }
相关文章推荐
- POJ1698 Alice's Chance(最大匹配)
- 【POJ】1698 Alice's Chance 最大流
- poj1698 - Alice's Chance (最大流)
- POJ_1698_Alice's Chance(最大流)
- poj 1698 Alice's Chance 拆点最大流
- poj 1698 Alice's Chance 【最大流 判断是否满流】
- poj 1698 Alice's Chance(最大流)
- POJ 1698 Alice's Chance(最大流)
- POJ 1698 Alice's Chance 最大流
- poj 1698 Alice's Chance 拆点最大流
- poj1698 - Alice's Chance (最大流)
- POJ 1698 Alice's Chance(最大流+拆点)
- poj 1698 Alice's Chance (最大流Dinic)
- POJ 1698--Alice's Chance【最大流 && 经典】
- POJ 1698 Alice's Chance
- POJ 1698 Alice's Chance
- poj 1698 Alice's Chance 二分图多重匹配
- POJ 1698 Alice's Chance ( EK )
- poj 1698 Alice's Chance(基础网络流·建图)
- POJ 1698 Alice's Chance (网络流)