poj1698 - Alice's Chance (最大流)
2014-02-24 21:37
288 查看
题目大意:爱丽丝要拍电影,有n部电影,规定爱丽丝每部电影在每个礼拜只有固定的几天可以拍电影,只可以拍前面w个礼拜,并且这部电影要拍d天,问爱丽丝能不能拍完所有的电影
第一行代表有多少组数据
对于每组数据第一行代表有n部电影
接下来2到n+1行,每行代表一个电影,每行9个数,前面7个数,1代表拍,0代表不拍,第8个数代表要拍几天,第9个数代表有几个礼拜时间拍
解题思路:
这题可以看做成二分图多重匹配,也可以用网络流实现,主要是建图,将图建好了就好说了
用s=0表示源点,t=371表示汇点....
1-20表示电影,因为电影最多只有20部
将371看做汇点的原因是,21-370表示每天,因为最多有50个星期
源点指向每部电影,最大容量为这部电影所拍摄的天数
电影指向天数,因为每天只能拍一部电影,若这天可以拍这部电影就表示最大容量为1
天数都指向汇点,最大容量都为1
这样建好图之后就可以直接从源点到汇点求最大流,看最大流是否等于每个电影天数相加只和,相等则可以拍完,不等则拍不完
第一行代表有多少组数据
对于每组数据第一行代表有n部电影
接下来2到n+1行,每行代表一个电影,每行9个数,前面7个数,1代表拍,0代表不拍,第8个数代表要拍几天,第9个数代表有几个礼拜时间拍
解题思路:
这题可以看做成二分图多重匹配,也可以用网络流实现,主要是建图,将图建好了就好说了
用s=0表示源点,t=371表示汇点....
1-20表示电影,因为电影最多只有20部
将371看做汇点的原因是,21-370表示每天,因为最多有50个星期
源点指向每部电影,最大容量为这部电影所拍摄的天数
电影指向天数,因为每天只能拍一部电影,若这天可以拍这部电影就表示最大容量为1
天数都指向汇点,最大容量都为1
这样建好图之后就可以直接从源点到汇点求最大流,看最大流是否等于每个电影天数相加只和,相等则可以拍完,不等则拍不完
#include <iostream> #include <cstdio> #include <algorithm> #include <memory.h> #include <queue> using namespace std; #define inf 0x7ffffff #define N 500 #define M 20000 int dis , cur ,gap ,head ,pre ; int nv,ne,s,t,top,max_week,sum; struct node { int u,v,c,next; }edge[M]; void init() { top = 0; memset(head,-1,sizeof(head)); s = 0; // start position max_week = -1; sum = 0; } void add_edge(int u,int v, int c) { edge[top].u=u; edge[top].v=v; edge[top].c=c; edge[top].next=head[u]; head[u]=top++; edge[top].u=v; edge[top].v=u; edge[top].c=0; edge[top].next=head[v]; head[v]=top++; } int sap() { int flow=0,max_flow=inf,u,v; memset(dis,0,sizeof(dis)); memset(gap,0,sizeof(gap)); for(int i=0; i<nv; i++) cur[i]=head[i]; gap[s]=nv; u=pre[s]=s; while(dis[s]<nv) { loop : for(int &j=cur[u]; j!=-1; j=edge[j].next) { v=edge[j].v; if(edge[j].c>0&&dis[u]==dis[v]+1) { if(edge[j].c<max_flow) max_flow=edge[j].c; pre[v]=u; u=v; if(v==t) { for(u=pre[v];v!=s;v=u,u=pre[u]) { edge[cur[u]].c-=max_flow; edge[cur[u]^1].c+=max_flow; } flow+=max_flow; max_flow=inf; } goto loop ; } } int mindis=nv; for(int j=head[u]; j!=-1; j=edge[j].next) { v=edge[j].v; if(edge[j].c>0&&dis[v]<mindis) { mindis=dis[v]; cur[u]=j; } } if((--gap[dis[u]])==0) break; gap[dis[u]=mindis+1]++; u=pre[u]; } return flow; } int main() { int i,j,k,h,time,ans,n,work[7],day,week; scanf("%d",&time); while(time--) { init(); scanf("%d",&n); for(i = 1; i <= n; ++i) { for(j = 0;j < 7; ++j) scanf("%d",&work[j]); scanf("%d%d",&day,&week); add_edge(s,i,day); //源点到电影连边 for(j = 0;j < week; ++j) for(k = 0;k < 7; ++k) if(work[k]) // can do add_edge(i,n+j*7+k+1,inf); //电影到固定的礼拜连边 max_week = max_week>week?max_week:week; //最多到几周 sum += day; } t = n+max_week*7+1; nv = t + 1; for(i = 0;i < max_week; ++i ) for(j = 1;j <= 7; ++j) add_edge(n+i*7+j,t,1); //天数与汇点连边 ans = sap(); // printf("%d ",ans); if(sum == ans) printf("Yes\n"); else printf("No\n"); } return 0; }
相关文章推荐
- POJ 1698 Alice's Chance(最大流)
- poj 1698 Alice's Chance 拆点最大流
- poj 1698 Alice's Chance(最大流)
- poj 1698 Alice's Chance (最大流Dinic)
- 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(基础网络流·建图)
- POJ 1698 Alice's Chance 网络流(水
- POJ 1698 Alice's Chance
- POJ 1698 Alice's Chance (网络流)
- POJ 1698 Alice's Chance