UVA 11248 Frequency Hopping(最小割)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37943488/article/details/81609050

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2205

题目大意:给一个有向网络,每条边均有一个容量,问是否存在一个点从点1到点N,流量为C的流,如果不存在,是否可以恰好修改一条弧的容量,使得存在一条这样的流

这道题真的让我欲仙欲死,从天亮写到天黑

先求一次网络流,如果最大流已经大于等于C,那么就可以输出答案了,因为我可以调节流量使得最后流量为C。如果小于,那么我们增大的就要是最小割里的弧,为什么呢?因为最大流=最小割,所以我们通过修改最小割里的边来使得流量增大。所以求出最小割的边以后,我们先使得所有的边的容量减去这条边上的流量,因为已经没有用了。然后将C加在最小割的边的容量上,再跑一次最大流,如果满足了大于等于C,就说明可以通过调节这条边的容量使得最大流增大。并且没必要每一次都跑完最大流,只要大于等于C了即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
#include<set>
using namespace std;
typedef long long ll;
const int maxn=10010;
const int maxm=2e5+7;
const ll inf=0x3f3f3f3f3f3f3f3fll;
int n,m;
struct Node
{
    int from;
    int to;
    ll capa;
    ll flow;
    int next;
}edge[maxm<<1];
int cnt;
ll C;
int head[maxn];
int dep[maxn];
int source,sink;
bool vis[maxn];
vector<int> vec;
vector<pair<int,int> > store;
void init()
{
    memset(head,-1,sizeof(head));
    store.clear();
    cnt=0;
    return;
}
void add(int u,int v,ll capa)
{
    edge[cnt].from=u;
    edge[cnt].to=v;
    edge[cnt].capa=capa;
    edge[cnt].flow=0;
    edge[cnt].next=head[u];
    head[u]=cnt++;
    edge[cnt].from=v;
    edge[cnt].to=u;
    edge[cnt].capa=0;
    edge[cnt].flow=0;
    edge[cnt].next=head[v];
    head[v]=cnt++;
    return;
}
bool bfs()
{
    memset(dep,-1,sizeof(dep));
    memset(vis,false,sizeof(vis));
    vis[source]=true;
    dep[source]=0;
    queue<int> que;
    que.push(source);
    while(!que.empty())
    {
        int node=que.front();
        que.pop();
        for(int i=head[node];~i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(edge[i].capa>edge[i].flow&&dep[v]==-1)
            {
                dep[v]=dep[node]+1;
                if(v==sink) return true;
                if(!vis[v])
                {
                    vis[v]=true;
                    que.push(v);
                }
            }
        }
    }
    return dep[sink]!=-1;
}
ll dfs(int node,ll minn)
{
    if(node==sink||minn==0)
    {
        return minn;
    }
    ll r=0;
    for(int i=head[node];~i;i=edge[i].next)
    {
        int v=edge[i].to;
        if(dep[v]==dep[node]+1)
        {
            ll tmp=dfs(v,min(minn,edge[i].capa-edge[i].flow));
            if(tmp>0)
            {
                edge[i].flow+=tmp;
                edge[i^1].flow-=tmp;
                r+=tmp;
                minn-=tmp;
                if(!minn) break;
            }
        }
    }
    if(!r) dep[node]=-1;
    return r;
}
ll dinic()
{
    ll maxflow=0;
    while(bfs())
    {
        maxflow+=dfs(source,inf);
        if(maxflow>=C) break;
    }
    return maxflow;
}
void getcut()
{
	bfs();
	for(int i=1;i<=n;i++)
    {
        for(int j=head[i];~j;j=edge[j].next)
        {
            int u=edge[j].from;
            int v=edge[j].to;
            if(dep[u]!=-1&&dep[v]==-1&&edge[j].capa>0&&edge[j].capa==edge[j].flow)
            {
                vec.push_back(j);
            }
        }
    }
	return;
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    ll cas=0;
    while(~scanf("%d%d%lld",&n,&m,&C))
    {
        init();
        if(!n&&!m&&!C) break;
        for(int i=0;i<m;i++)
        {
            int u,v;
            ll w;
            scanf("%d%d%lld",&u,&v,&w);
            add(u,v,w);
        }
        source=1;
        sink=n;
        ll ans=dinic();
        if(ans>=C||C==0)
        {
            printf("Case %lld: possible\n",++cas);
        }
        else
        {
            vec.clear();
            se.clear();
        	getcut();
        	for(int i=1;i<=n;i++)
            {
                for(int j=head[i];~j;j=edge[j].next)
                {
                    edge[j].capa-=edge[j].flow;
                }
            }
            int len=vec.size();
            for(int i=0;i<len;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    for(int k=head[j];~k;k=edge[k].next)
                    {
                        edge[k].flow=0;
                    }
                }
                int index=vec[i];
                edge[index].capa+=C;
                if(ans+dinic()>=C)
                {
                    store.push_back(make_pair(edge[index].from,edge[index].to));
                }
                edge[index].capa-=C;
            }
            if(store.empty())
            {
                printf("Case %lld: not possible\n", ++cas);
            }
            else
            {
                sort(store.begin(),store.end());
                printf("Case %lld: possible option:(%d,%d)",++cas,store[0].first,store[0].second);
                int lenlen=store.size();
                for(int i=1;i<lenlen;i++)
                {
                    printf(",(%d,%d)",store[i].first,store[i].second);
                }
                puts("");
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37943488/article/details/81609050