UVA 11248 Frequency Hopping (最大流模板)

题意:给定一个网络,每条边都有一个容量,问是否存在1到n的流量为c的流。如果存在,输出possible,如果不存在,是否可以通过修改一条这样的边的容量,使得存在这样的流?如果有若干个答案,排序后输出。

题解:求出最大流,如果大于等于c,就存在,否则,算出最小割,如果,把最小割中的流量增加到c,再求最大流,如果此时的最大流满足大于c,保存答案。因为这样写会超时,所以用到白书给的两个优化。

code:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define pb push_back
using namespace std;
 
const int maxn = 105,inf = 2e9+10000;
 
struct Edge{
    
    
    int from,to,cap,flow;
};
 
bool cmp(const Edge& a,const Edge& b)
{
    
    
    return a.from < b.from||(a.from==b.from&&a.to<b.to);
}
 
struct Dinic{
    
    
    int n,m,s,t;
    vector<Edge>edges;
    vector<int>g[maxn];
    bool vis[maxn];
    int d[maxn];
    int cur[maxn];
    void init(int n)
    {
    
    
        this->n=n;
        for(int i=0;i<=n;i++)g[i].clear();
        edges.clear();
    }
    void AddEdge(int from,int to,int cap)
    {
    
    
        edges.push_back((Edge){
    
    from,to,cap,0});
        edges.push_back((Edge){
    
    to,from,0,0});
        m=edges.size();
        g[from].push_back(m-2);
        g[to].push_back(m-1);
    }
    bool BFS()
    {
    
    
    	memset(vis,0,sizeof(vis));
        queue<int>q;
        q.push(s);
        d[s]=0;
        vis[s]=1;
        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 s,int t,int need)
    {
    
    
        this->s=s;
        this->t=t;
        int flow=0;
        while(BFS())
        {
    
    
        	memset(cur,0,sizeof(cur));
            flow+=DFS(s,inf);
            if(flow>=need)return flow;
        }
        return flow;
    }
    
    vector<int> Mincut()
    {
    
    
        vector<int>ans;
        for(int i=0;i<edges.size();i++)
        {
    
    
            Edge& e=edges[i];
            if(vis[e.from]&&!vis[e.to]&&e.cap>0)
                ans.push_back(i);
        }
        return ans;
    }
    void Reduce()
    {
    
    
        for(int i=0;i<edges.size();i++)
            edges[i].cap-=edges[i].flow;
    }
    void ClearFlow()
    {
    
    
        for(int i=0;i<edges.size();i++)
            edges[i].flow=0;
    }
}sol;
 
int main()
{
    
    
    int n,m,c,kase = 0;
    while(~scanf("%d%d%d",&n,&m,&c)&&n)
    {
    
    
    	int u,v,w;
    	sol.init(n);
    	for(int i=1;i<=m;i++)
    	{
    
    
    		scanf("%d%d%d",&u,&v,&w);
    		sol.AddEdge(u,v,w);
		}
		printf("Case %d: ",++kase);
		int flow = sol.Maxflow(1,n,inf);
		if(flow >= c)puts("possible");
		else
		{
    
    
			vector<int> cut = sol.Mincut();
			sol.Reduce();
			vector<Edge>ans;
			for(int i=0;i<cut.size();i++)
			{
    
    
				Edge& e = sol.edges[cut[i]];
				int tmp = e.cap; 
				e.cap = c;
				sol.ClearFlow();
				if(flow + sol.Maxflow(1,n,c-flow) >= c)ans.pb(e);
				e.cap = tmp;
			}
			if(ans.size() == 0)puts("not possible");
			else
			{
    
    
				sort(ans.begin(),ans.end(),cmp);
				printf("possible option:(%d,%d)",ans[0].from,ans[0].to);
				for(int i=1;i<ans.size();i++)printf(",(%d,%d)",ans[i].from,ans[i].to);
				printf("\n");
			}
		}
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44499508/article/details/107140988
今日推荐