網絡流 poj 1698

        Alice 要拍電影,每天智能拍一部電影,現在有幾部電影讓他去拍,每部電影都有要求至少拍的天數和必須要在前幾個禮拜拍完。

     

網絡流的題目:

       將這幾個禮拜的天數全部拆成點,將所有點和這天能拍的所有電影連一條流量爲1的邊,原點與天數相連邊權爲1,所有電影與匯點相連,流量爲電影所需天數。


      注意:在加邊的時候別忘了,如果now_week>week[i] 就不要將這天和電影i相連了。


282ms 代碼     算法  Edmonds_Karp  鄰接表


#include <iostream>
#include <queue>
#include <cstring>
#include <vector>
#define N 2000
#define p 800
#define INF 0x3f3f3f3f
using namespace std;
const int q=2*p;
int T,n,days;
int total=0;
int arr[N][N];
int f[N];
int a[N];
int week[N];
int R = 0;
vector<int> tab[N];
struct Edge
{
  int u,v,cap,flow;
  Edge(int a = 0,int b = 0,int c = 0):u(a),v(b),cap(c),flow(0){}
}edge[N*N/20];

void reset()
{
	R = 0;
	for (int i=0;i<N;++i)
	  tab[i].clear();
}

void AddEdge(int a,int b,int c)
{
	edge[R]=Edge(a,b,c);
	tab[a].push_back(R++);
	edge[R]=Edge(b,a);
	tab[b].push_back(R++);
}
int flow[N];
int pre[N];
bool done[N];
int Edmonds_Karp(int s=0,int t=q)
{

	int max_flow=0;
	while(1)
	{
		for (int i=0;i<N;++i)pre[i]=-1;
		memset(flow,0,sizeof(flow));
		flow[s] = INF;
		queue<int> Q;
		Q.push(s);
		while(!Q.empty())
		{
			int x = Q.front(); Q.pop();
			for (int i = 0; i < tab[x].size(); ++i)
			{
				Edge & e = edge[tab[x][i]];
				if(pre[e.v] == -1 && e.cap > e.flow)
				{
					pre[e.v] = tab[x][i];
					flow[e.v] = min(e.cap - e.flow, flow[x]);
					Q.push(e.v);
				}
			}
			if(flow[t] != 0)break;
		}
		if(flow[t] == 0)break;
		max_flow += flow[t];
		for (int u = t; u != s; u=edge[pre[u]].u)
		{
			edge[pre[u]].flow += flow[t];
			edge[pre[u]^1].flow -= flow[t];
		}
		
	}
	return max_flow;
	
}
int counter = 0;
int main()
{
	bool flag;
	int x = 0; //temp variable
	cin >> T;
	while(T--)
	{
		memset(done,0,sizeof(done));
		counter = 60;
		int max_weeks = 0;
		reset();
		flag = 1;
		total = 0;
		scanf("%d",&n);
		for (int k=1;k<=n;++k)
		{
		  for (int i = 1;i <= 7;++i)        //input
			scanf("%d", &arr[k][i]);
	      cin >> f[k] >> week[k];
	      total += f[k];
	   }
	//  AddEdges,which is the most important
	
	  for (int i = 1; i <= n; ++i)
	      AddEdge(i,q,f[i]);

	for (int k = 1; k <= n ;++k)
	  	for (int j = 1 ;j <= week[k]; ++j)
	  	 for (int i = 1; i <= 7;++i)	   
	  	 {
	  	   if(arr[k][i])
	  	     AddEdge(j*7+i,k,1);
	  	   if(!done[j*7+i])
	  	   {
	  	   	 done[j*7+i] = 1;
	  	   	 AddEdge(0,j*7+i,1);
		   }
	  	 }
	  int q = Edmonds_Karp();
	  if(q == total )
	    printf("Yes\n");
	else printf("No\n");	
	}
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章