poj Alice's Chance(最大流解题)

题目信息:Alice's Chance

解法:

    利用最大网络流,以0表示源点,1表示汇点,以源点建立与每一天的边,边的容量是1,根据题目数据建立每周的给定的一天与每个电影之间的边,容量为1,建立每个film与汇点的边,容量为该部电影所需花费的时间,求出最大流和每部电影所花费天数的和比较,相等输出yes,否则输出No

源代码:

//Accepted 2196K 922MS 
//很险差点超时 
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
#define VEX 500
int cpt[VEX][VEX],flow[VEX][VEX];
int sum;
int f[7];
int Edmonds_Karp(int src,int sink,int node)
 {
     
     int d[VEX],pre[VEX];//d是增广路长度,pre记录前驱;
     int i,j;
 
     memset(flow,0,sizeof(flow));
     while(true)
     {
         memset(pre,-1,sizeof(pre));
         d[src]=0x7fffffff;
         queue<int> que;
         que.push(src);
         while(!que.empty() && pre[1]<0)
         {
             int t=que.front();
             que.pop();
             for(i=0;i<node;++i)
             {
                 if(pre[i]<0 && (j=cpt[t][i]-flow[t][i]))
                 {
                     pre[i]=t;
                     que.push(i);
                     d[i]=min(d[t],j);
                 }
             }
             
         }
         if(pre[sink]<0) break;
         for(i=1;i!=0;i=pre[i])
         {
             flow[pre[i]][i]+=d[1];
             flow[i][pre[i]]-=d[1];
         }
     }
     for(j=i=0;i<node;j+=flow[0][i++]);
     return j;
 }
int Init()
{
   sum=0;
   int Maxw=0;//记录跨度最长的电影需要周数 
   int n,i,j;
   int D,W;
   int filmNum=0;
   memset(cpt,0,sizeof(cpt)); 
   cin>>n;
   //0 is the source,1 is the sink,and the2--21 is the films,the 22--500 is the days
   for(i=22;i<500;++i) cpt[0][i]=1;  
   while(n--)
   {
       for(i=0;i<7;++i)
           cin>>f[i];
       cin>>D>>W;
       sum+=D;
       if(Maxw<W) Maxw=W; 
       cpt[filmNum+2][1]=D;
       int temp=W*7;
       for(i=0;i<temp;i+=7)
       {
          for(j=0;j<7;++j)
          {
              cpt[22+i+j][filmNum+2]=f[j];
          }
       }   
       filmNum++;       
   }
   return 22+7*Maxw; 
}
int main()
{
    int T;//the number of test cases
    cin>>T;
    while(T--)
    {
        int node=Init();
        int temp=Edmonds_Karp(0,1,node);
        //cout<<temp<<" "<<sum<<endl;
        if(sum==temp)
            cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
    return 0;
    
}
原文地址:https://www.cnblogs.com/redlight/p/2488161.html