UVA 11248 Salto de frecuencia (plantilla de flujo máximo)

El significado de la pregunta: Dada una red, cada lado tiene una capacidad, pregunte si hay un flujo de tráfico c de 1 a n. Si existe, salida posible, si no existe, ¿es posible modificar la capacidad de tal borde para hacer que tal flujo exista? Si hay varias respuestas, envíelas después de ordenarlas.

Solución del problema: encuentre el caudal máximo, si es mayor o igual ac, existe, de lo contrario, calcule el corte mínimo, si, aumente el caudal en el corte mínimo ac, luego encuentre el caudal máximo, si el caudal máximo en este momento es mayor que c, guarde la respuesta . Debido a que escribir de esta manera se agotará, se utilizan las dos optimizaciones proporcionadas por el libro blanco.

código:

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

Supongo que te gusta

Origin blog.csdn.net/weixin_44499508/article/details/107140988
Recomendado
Clasificación