UVA 11248 Frequency Hopping (maximum flow template)

The meaning of the question: Given a network, each side has a capacity, ask whether there is a flow of traffic c from 1 to n. If it exists, output possible. If it does not exist, is it possible to modify the capacity of such an edge to make such a flow exist? If there are several answers, output after sorting.

Problem solution: find the maximum flow, if it is greater than or equal to c, it exists, otherwise, calculate the minimum cut, if, increase the flow in the minimum cut to c, then find the maximum flow, if the maximum flow at this time is greater than c, save the answer . Because writing in this way will time out, the two optimizations given by the white book are used.

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;
}

Guess you like

Origin blog.csdn.net/weixin_44499508/article/details/107140988