UVA11248_Frequency Hopping

给一个有向网络,求其1,n两点的最大流量是否不小于C,如果小于,是否可以通过修改一条边的容量使得最大流量不小于C?

首先对于给定的网络,我们可以先跑一遍最大流,然后先看流量是否大于C。

然后保存跑完第一次最大流后的残余网络容量情况,然后接下来对于每条割,将分别其容量加C-maxflow,看看能否得到满足条件的流量即可。

召唤代码君:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <algorithm>
#define maxn 1110
#define maxm 222220
#define mp(x,y) make_pair(x,y)
using namespace std;

typedef pair<int,int> pr;
int C[maxm];
int to[maxm],next[maxm],c[maxm],first[maxn],edge;
int d[maxn],tag[maxn],TAG=222;
bool can[maxn];
int Q[maxn],bot,top;
int n,m,cmax,s,t,cas=0;
vector<pr> ans;

void _init()
{
    edge=-1;
    s=1,t=n;
    for (int i=1; i<=n; i++) first[i]=-1;
}

void addedge(int U,int V,int W)
{
    edge++;
    to[edge]=V,c[edge]=W,next[edge]=first[U],first[U]=edge;
    edge++;
    to[edge]=U,c[edge]=0,next[edge]=first[V],first[V]=edge;
}

bool bfs()
{
    Q[bot=top=1]=t,d[t]=0,tag[t]=++TAG,can[t]=false;
    while (bot<=top)
    {
        int cur=Q[bot++];
        for (int i=first[cur]; i!=-1; i=next[i])
            if (c[i^1]>0 && tag[to[i]]!=TAG)
            {
                d[to[i]]=d[cur]+1,Q[++top]=to[i];
                can[to[i]]=false,tag[to[i]]=TAG;
                if (to[i]==s) return true;
            }
    }
    return false;
}

int dfs(int cur,int num)
{
    if (cur==t) return num;
    int tmp=num,k;
    for (int i=first[cur]; i!=-1; i=next[i])
        if (c[i]>0 && tag[to[i]]==TAG && d[to[i]]==d[cur]-1 && !can[to[i]])
        {
            k=dfs(to[i],min(num,c[i]));
            if (k) num-=k,c[i]-=k,c[i^1]+=k;
            if (!num) break;
        }
    if (num) can[cur]=true;
    return tmp-num;
}

int maxflow()
{
    int flow=0;
    while (bfs()) flow+=dfs(s,cmax);
    return flow;
}

int main()
{
    int U,V,W,last;
    while (scanf("%d%d%d",&n,&m,&cmax) && (n))
    {
        _init();
        for (int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&U,&V,&W);
            addedge(U,V,W);
        }
        printf("Case %d: ",++cas);
        last=maxflow();
        if (last>=cmax)
        {
            puts("possible");
            continue;
        }
        ans.clear();
        for (int i=0; i<=edge; i++) C[i]=c[i];
        for (int i=0; i<=edge; i+=2)
        {
            if (c[i]+c[i+1]>cmax) continue;
            c[i]+=cmax-last-c[i];
            if (last+maxflow()>=cmax) ans.push_back(mp(to[i+1],to[i]));
            for (int j=0; j<=edge; j++) c[j]=C[j];
        }
        if (ans.size()==0) puts("not possible");
        else
        {
            sort(ans.begin(),ans.end());
            printf("possible option:(%d,%d)",ans[0].first,ans[0].second);
            for (unsigned i=1; i<ans.size(); i++)
                printf(",(%d,%d)",ans[i].first,ans[i].second);
            printf("\n");
        }
    }
    return 0;
}

UVA11248_Frequency Hopping,布布扣,bubuko.com

时间: 2024-10-23 17:49:52

UVA11248_Frequency Hopping的相关文章

uva 10801 - Lift Hopping(最短路Dijkstra)

1 /* 2 题目大意: 3 就是一幢大厦中有0-99的楼层, 然后有1-5个电梯!每个电梯有一定的上升或下降速度和楼层的停止的位置! 4 问从第0层楼到第k层最少经过多长时间到达! 5 6 思路:明显的Dijkstra ,在建图的时候u->v可能有多个电梯到达,取时间最少的当作路径的权值! 7 如果我们发现 d[i] > d[j] + map[j][i] + 60, 那么说明从第0层到达第 i 层的时间大于从第j层 8 转移到其他电梯然后到达第 i 层的时间,那么就更新d[i]的值! 9 1

uva 11248 Frequency Hopping (最大流)

uva 11248 Frequency Hopping 题目大意:给定一个有向网络,每条边均有一个容量. 问是否存在一个从点1到点N.流量为C的流.假设不存在,能否够恰好改动一条弧的容量,使得存在这种流. 解题思路:先依照题目给出的边建好图,然后跑一发最大流,得到原始最大流C1,假设C1==C或者C==0时.能够直接输出possible.假设不存在这种流.那么開始找割边,将这些割边的容量添加C,再求最大流.假设能够,那么要输出全部的方案.改动全部割边后,仍没有符合条件的流,输出 not poss

[UVA 10801]Lift Hopping[Dijkstra][建图]

题目链接:[UVA 10801]Lift Hopping[Dijkstra][建图] 题意分析: 从0层开始,一共有n台电梯供你到达目的地k层.每台电梯往上走一层都要消耗t[i]的时间,并且电梯只能在特定的楼层停下,换乘电梯要花费60s的时间,而且呢,你不能用楼梯上楼,只能搭电梯....(hentai!)问:最快到达楼层k的时间是多少?不能到达就输出-1. 解题思路: 这题技巧就是体现在建图上,图建好了,用dijkstra跑一遍就行了. 具体建图就是用mp[i][j]代表从楼层i到楼层j的最小距

UVA 10801 Lift Hopping (最短路)

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1742 Problem ? Lift Hopping Time Limit: 1 second Ted the bellhop: "I'm coming up and if there isn't a dead body by the time I get there, I'll m

【UVA】821-Page Hopping(Floyd)

模板题,求一个点到任何一点的距离,用Floyd就行了,结点不一定是从1 ~ n 的,所以需要记录结点的id 14063895 821 Page Hopping Accepted C++ 0.119 2014-08-19 10:00:27 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #include<sta

UVa10801_Lift Hopping(最短路)(小白书图论专题)

解题报告 思路 神奇的电梯,我的思路是直接整出一个超级源点和超级汇点(貌似这是网络流的叫法,,,sad) 源点与所有有在0层的电梯连线,汇点与k层连线,然后每个电梯如果有在同一层的连60s的线,对于每个电梯可以到达的每一层连一条线,处理层和电梯就直接用类似于离散化的方式处理,比如说第一个电梯可以有n个层可以到,第二个电梯有m个层可以到,那么就有1-n+m的点,源点0,汇点n+m+1: 做完看来别人的解题报告,发现我的想法很辍,因为只有在换电梯的时候才要松弛加上60,用邻接矩阵处理就很好. 智商捉

[题解]UVA10801 Lift Hopping

链接:http://vjudge.net/problem/viewProblem.action?id=22172 描述:有n部电梯,每部电梯都有不能停下的楼层,要求搭乘电梯从第0层到第k层. 思路:单源点最短路 建图:将每层楼拆成n个点,用边权解决换乘等待的时间.将每部电梯能到达的楼层顺次连接,边权是该电梯经过所需时间.最后建立一个超级源点S,连接每部电梯的第0层的节点,边权为0,方便统计答案. 下面是我的实现,Dijkstra版本: 1 #include <iostream> 2 #incl

UVA 11248 Frequency Hopping

Frequency Hopping Time Limit: 10000ms Memory Limit: 131072KB This problem will be judged on UVA. Original ID: 1124864-bit integer IO format: %lld      Java class name: Main 20th July, 1942 Colonel Al Pacheno,According to the previous order “ref:   23

UVA 11248 - Frequency Hopping(网络流)

UVA 11248 - Frequency Hopping 题目链接 题意:给定一个网络,现在需要从1到N运输流量C,问是否可能,如果可能输出可能,如果不可能,再问是否能通过扩大一条边的容量使得可能,如果可以输出这些边(按u先排再按v排),如果不行输出不可能 思路:先做一遍网络流,然后每次在最小割上进行增加容量,需要两个优化,每次找流量找到>= c就可以了,然后每次修改容量,可以直接从之前做过的网络流继续做即可 代码: #include <cstdio> #include <cst