概述
题意:爱丽丝喜欢拍电影,现在正好有N个公司找她拍电影,每部电影都指定在每周的星期几拍,要用D天拍完电影,最迟M个星期要拍完.问爱丽丝能不能拍完所有电影.
分析:350天各为一个顶点,每个顶点都有且只有一条边指向汇点t,容量为1,源点为爱丽丝,指向每部电影,权值为该部电影拍完的天数D,每部电影都向能拍这部电影的那一天的顶点建一条权值为1的边.如果计算出来的最大流为所有电影要拍的天数的总和则能够拍完所有电影,否则不能.
1 #include <cstdio> 2 #include <cstring> 3 const int MAXN=375;//点数的最大值 4 const int MAXM=14740;//边数的最大值 5 const int INF=0x3fffffff; 6 7 struct Node 8 { 9 int from,to,next; 10 int cap; 11 }edge[MAXM]; 12 13 int tol; 14 int head[MAXN]; 15 int dep[MAXN]; 16 int gap[MAXN];//gap[x]=y :说明残留网络中dep[i]==x的个数为y 17 18 int n;//n是总的点的个数,包括源点和汇点 19 20 void init() 21 { 22 tol=0; 23 memset(head,-1,sizeof(head)); 24 } 25 26 void addedge(int u,int v,int w) 27 { 28 edge[tol].from=u; 29 edge[tol].to=v; 30 edge[tol].cap=w; 31 edge[tol].next=head[u]; 32 head[u]=tol++; 33 edge[tol].from=v; 34 edge[tol].to=u; 35 edge[tol].cap=0; 36 edge[tol].next=head[v]; 37 head[v]=tol++; 38 } 39 void BFS(int start,int end) 40 { 41 memset(dep,-1,sizeof(dep)); 42 memset(gap,0,sizeof(gap)); 43 gap[0]=1; 44 int que[MAXN]; 45 int front,rear; 46 front=rear=0; 47 dep[end]=0; 48 que[rear++]=end; 49 while(front!=rear) 50 { 51 int u=que[front++]; 52 if(front==MAXN)front=0; 53 for(int i=head[u];i!=-1;i=edge[i].next) 54 { 55 int v=edge[i].to; 56 if(dep[v]!=-1)continue; 57 que[rear++]=v; 58 if(rear==MAXN)rear=0; 59 dep[v]=dep[u]+1; 60 ++gap[dep[v]]; 61 } 62 } 63 } 64 int SAP(int start,int end) 65 { 66 int res=0; 67 BFS(start,end); 68 int cur[MAXN]; 69 int S[MAXN]; 70 int top=0; 71 memcpy(cur,head,sizeof(head)); 72 int u=start; 73 int i; 74 while(dep[start]<n) 75 { 76 if(u==end) 77 { 78 int temp=INF; 79 int inser; 80 for(i=0;i<top;i++) 81 if(temp>edge[S[i]].cap) 82 { 83 temp=edge[S[i]].cap; 84 inser=i; 85 } 86 for(i=0;i<top;i++) 87 { 88 edge[S[i]].cap-=temp; 89 edge[S[i]^1].cap+=temp; 90 } 91 res+=temp; 92 top=inser; 93 u=edge[S[top]].from; 94 } 95 if(u!=end&&gap[dep[u]-1]==0)//出现断层,无增广路 96 break; 97 for(i=cur[u];i!=-1;i=edge[i].next) 98 if(edge[i].cap!=0&&dep[u]==dep[edge[i].to]+1) 99 break; 100 if(i!=-1) 101 { 102 cur[u]=i; 103 S[top++]=i; 104 u=edge[i].to; 105 } 106 else 107 { 108 int min=n; 109 for(i=head[u];i!=-1;i=edge[i].next) 110 { 111 if(edge[i].cap==0)continue; 112 if(min>dep[edge[i].to]) 113 { 114 min=dep[edge[i].to]; 115 cur[u]=i; 116 } 117 } 118 --gap[dep[u]]; 119 dep[u]=min+1; 120 ++gap[dep[u]]; 121 if(u!=start)u=edge[S[--top]].from; 122 } 123 } 124 return res; 125 } 126 int main() 127 { 128 int T,N,f[7],D,W; 129 scanf("%d",&T); 130 n = 372; 131 int s = 370,t = 371; 132 while(T--) 133 { 134 scanf("%d",&N); 135 init(); 136 int sum = 0; 137 for(int i = 0;i < N;i++) 138 { 139 for(int j = 0;j < 7;j++) 140 { 141 scanf("%d",&f[j]); 142 } 143 scanf("%d%d",&D,&W); 144 sum += D; 145 for(int j = 0;j < 7;j++) 146 { 147 if(f[j]) 148 { 149 for(int k = 0;k < W;k++) 150 { 151 addedge(350 + i,k * 7 + j,1); 152 } 153 } 154 } 155 addedge(s,350 + i,D); 156 } 157 for(int j = 0;j < 350;j++) 158 { 159 addedge(j,t,1); 160 } 161 if(SAP(s,t) == sum) 162 printf("Yesn"); 163 else 164 printf("Non"); 165 } 166 }
转载于:https://www.cnblogs.com/ZShogg/p/3230309.html
最后
以上就是专注航空为你收集整理的poj 1698的全部内容,希望文章能够帮你解决poj 1698所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复