• poj 1698 Alice's Chance 网络流


    以电影为x节点,天数为y节点,如果电影a需在w周之前完成,那么连接该电影节点到前w周能去的那几天,容量为1,源点s点连接每个电影节点,容量为该电影需要去的天数,每一天连接汇点 t ,容量为1,表示每天只能去一个,求最大流,如果最大流等于所有应去的天数,则输出yes,否则no。

    #include <cstdio>
    #include <vector>
    #include <queue>
    using namespace std;
    #define maxn 1000
    #define INF 100000
    struct Edge 
    {
    	int from, to, cap, flow;
    };
    
    int s, t;
    vector<Edge> edges;    // 边数的两倍
    vector<int> G[maxn];   // 邻接表,G[i][j]表示结点i的第j条边在e数组中的序号
    bool vis[maxn];        // BFS使用
    int d[maxn];           // 从起点到i的距离
    int cur[maxn];         // 当前弧指针
    int min(int a,int b)
    {
    	if(a<b) return a;
    	else return b;
    }
    void AddEdge(int from, int to, int cap) 
    {
    	int len;
    	Edge temp;
    	temp.from=from;temp.to=to;temp.cap=cap;temp.flow=0;
    	edges.push_back(temp);
    	temp.from=to;temp.to=from;temp.cap=0;temp.flow=0;
        edges.push_back(temp);
        len = edges.size();
        G[from].push_back(len-2);
        G[to].push_back(len-1);
    }
    bool BFS() 
    {
    	memset(vis, 0, sizeof(vis));
        queue<int> Q;
        Q.push(s);
        vis[s] = 1;
        d[s] = 0;
        while(!Q.empty()) 
    	{
    		int x = Q.front(); Q.pop();
    		for(int i = 0; i < G[x].size(); i++) 
    		{
    			Edge& e = edges[G[x][i]];
    			if(!vis[e.to] && e.cap > e.flow) 
    			{
    				vis[e.to] = 1;
    				d[e.to] = d[x] + 1;
    				Q.push(e.to);
    			}
    		}
        }
        return vis[t];
    }
    int DFS(int x, int a) 
    {
    	if(x == t || a == 0) return a;
        int flow = 0, f;
        for(int& i = cur[x]; i < G[x].size(); i++) 
    	{
    		Edge& e = edges[G[x][i]];
    		if(d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap-e.flow))) > 0) 
    		{
    			e.flow += f;
    			edges[G[x][i]^1].flow -= f;
    			flow += f;
    			a -= f;
    			if(a == 0) break;
    		}
        }
        return flow;
    }
    int Maxflow() 
    {
        int flow = 0;
        while(BFS()) 
    	{
    		memset(cur, 0, sizeof(cur));
    		flow += DFS(s, INF);
        }
        return flow;
    }
    int main()
    {
    	int T,N,D[55],W[55],K[55][12];
    	scanf("%d",&T);
    	while(T--)
    	{
    		int i,j,l;
    		int max=0,sum=0;
    		scanf("%d",&N);
    		for(i=1;i<=N;i++)
    		{
    			for(j=1;j<=7;j++)
    				scanf("%d",&K[i][j]);
    			scanf("%d",&D[i]);
    			sum+=D[i];
    			scanf("%d",&W[i]);
    			if(W[i]>max) max=W[i];
    		}
    		s=0; t=max*7+N+1;
    		for(i=0;i<=t+5;i++) G[i].clear();
    		for(i=1;i<=N;i++)
    		{
    			AddEdge(s,i,D[i]);
    			for(j=1;j<=7;j++)
    			{
    				if(K[i][j]==1) 
    					for(l=1;l<=W[i];l++)
    						AddEdge(i,(l-1)*7+j+N,1);
    			}
    		}
    		for(i=N+1;i<t;i++) AddEdge(i,t,1);
    		if(Maxflow()==sum)
    			printf("Yes
    ");
    		else printf("No
    ");
    	}
    	return 0;
    }
    


     

  • 相关阅读:
    C++用于修饰的keyword
    UVa 884
    yii 使用 mongodb 小工具 YiiMongoDbSuite
    三种网络协议握手
    学习设计模式的前世今生
    B二分法
    链接链接新手变化需要注意哪些问题
    插值与拟合 课件链接
    UVa 740
    疯狂暑期学习计划~~~
  • 原文地址:https://www.cnblogs.com/vermouth/p/3710162.html
Copyright © 2020-2023  润新知