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;

    

}

 

你可能感兴趣的:(poj)