uva 11248 Frequency Hopping

题目大意:给定一个有向网络,每条边均有一个容量。

问是否存在一个从点1到点N。流量为C的流。假设不存在,能否够恰好改动一条弧的容量,使得存在这种流。

解题思路:先依照题目给出的边建好图,然后跑一发最大流,得到原始最大流C1,假设C1==C或者C==0时。能够直接输出possible。假设不存在这种流。那么開始找割边,将这些割边的容量添加C,再求最大流。假设能够,那么要输出全部的方案。改动全部割边后,仍没有符合条件的流,输出 not possible。

优化:1)第一次跑最大流的每条边的流量情况,能够留着,接下来能够在它的基础上增广。2)每次求最大流,不用求完,当流符合条件即>=C时,就可以返回成功。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <queue>
using namespace std; typedef long long ll;
const int N = 505;
const int M = 20005;
const ll INF = 1e18;
int n, e, s, t ;
ll c;
struct Edge{
int from, to;
ll cap, flow;
}; int cmp(Edge a, Edge b) {
if (a.from != b.from) return a.from < b.from;
else return a.to < b.to;
} struct Dinic{
vector<Edge> edges, tempOE;
vector<int> G[M];
vector<int> MCut;
Edge rec[M];
int vis[N], d[N];
int cur[M];
ll ans; void init() {
ans = 0;
for (int i = 0; i < e; i++) G[i].clear();
edges.clear();
} void addEdge(int from, int to, ll cap) {
edges.push_back((Edge){from, to, cap, 0});
edges.push_back((Edge){to, from, 0, 0});
int m = edges.size();
G[from].push_back(m - 2);
G[to].push_back(m - 1);
} int BFS() {
memset(vis, 0, sizeof(vis));
queue<int> Q;
Q.push(s);
d[s] = 0;
vis[s] = 1;
while (!Q.empty()) {
int u = Q.front(); Q.pop();
for (int i = 0; i < G[u].size(); i++) {
Edge &e = edges[G[u][i]];
if (!vis[e.to] && e.cap > e.flow) {
vis[e.to] = 1;
d[e.to] = d[u] + 1;
Q.push(e.to);
}
}
}
return vis[t];
} ll DFS(int u, ll a) {
if (u == t || a == 0) return a;
ll flow = 0, f;
for (int &i = cur[u]; i < G[u].size(); i++) {
Edge &e = edges[G[u][i]];
if (d[u] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0) {
e.flow += f;
edges[G[u][i]^1].flow -= f;
flow += f;
a -= f;
if (a == 0) break;
}
}
return flow;
} bool MF() {
while (BFS()) {
memset(cur, 0, sizeof(cur));
ans += DFS(s, INF);
if (ans >= c) return true; //不用完整地求最大流,当流量大于等于c时,该改动就是可行的
}
return false;
} void getMincut() { //求最小割
MCut.clear();
for (int i = 0; i < edges.size(); i += 2) {
if (vis[edges[i].from] && !vis[edges[i].to]) {
MCut.push_back(i);
}
}
} int solve() {
int cnt = 0;
tempOE.clear();
getMincut();
ll f = ans; //求完初始最大流,记录当前总流量
int es = edges.size();
for (int i = 0; i < es; i++) tempOE.push_back(edges[i]); //记录初始最大流每条边的情况
int cs = MCut.size();
for (int i = 0; i < cs; i++) {
edges[MCut[i]].cap = edges[MCut[i]].flow + c;
if (MF()) {
rec[cnt++] = edges[MCut[i]]; //若将该边的容量加上c之后。总流量大于等于c。则改动该边是可行方案。记录该边
}
ans = f; //每改动一条边。且检验完之后,恢复初始状态
edges.clear();
for (int i = 0; i < es; i++) edges.push_back(tempOE[i]);
}
return cnt;
}
}din; void input() {
s = 1, t = n;
int u, v;
ll cap;
for (int i = 0; i < e; i++) {
scanf("%d %d %lld", &u, &v, &cap);
din.addEdge(u, v, cap);
}
} void solve() {
if (din.MF() || c == 0) {
printf("possible\n");
return;
}
int cnt = din.solve();
if (!cnt) {
printf("not possible\n");
return;
}
sort(din.rec, din.rec + cnt, cmp); //记得排序
printf("possible option:(%d,%d)", din.rec[0].from, din.rec[0].to);
for (int i = 1; i < cnt; i++) {
printf(",(%d,%d)", din.rec[i].from, din.rec[i].to);
}
puts("");
} int main() {
int Case = 1;
while (scanf("%d %d %lld", &n, &e, &c) == 3) {
if (!n && !e && !c) break;
din.init();
printf("Case %d: ", Case++);
input();
solve();
}
return 0;
}

uva 11248 Frequency Hopping (最大流)的更多相关文章

  1. UVA 11248 - Frequency Hopping(网络流量)

    UVA 11248 - Frequency Hopping 题目链接 题意:给定一个网络,如今须要从1到N运输流量C,问是否可能,假设可能输出可能,假设不可能,再问能否通过扩大一条边的容量使得可能,假 ...

  2. UVA 11248 Frequency Hopping

    Frequency Hopping Time Limit: 10000ms Memory Limit: 131072KB This problem will be judged on UVA. Ori ...

  3. UVa 11248 Frequency Hopping (网络流)

    题意:给定上一个网络,每个边有一个容量,问你能不能从 1 到 n,使得流量为 c,如果不能,那么是不是可以修改一条边,使得达到. 析:背景就是一个网络流,如果原图能跑出来,那么就不用了,就肯定能达到, ...

  4. Uvaoj 11248 Frequency Hopping(Dinic求最小割)

    题意:1到n节点(节点之间有一定的容量),需要流过C的流量,问是否可以?如果可以输出possible, 否则如果可以扩大任意一条边的容量 可以达到目的,那么输出possible option:接着输出 ...

  5. UVa11248 Frequency Hopping(最大流+最小割)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33206 [思路] 最大流最小割. 可以确定的是如果不可行需要修改的 ...

  6. UVa 11248 网络扩容(最大流(需要优化))

    https://vjudge.net/problem/UVA-11248 题意: 给定一个有向网络,每条边均有一个容量.问是否存在一个从点1到点N,流量为C的流.如果不存在,是否可以恰好修改一条弧的容 ...

  7. UVA-11248 Frequency Hopping (最大流+最小割)

    题目大意:给一张网络,问是否存在一条恰为C的流.若不存在,那是否存在一条弧,使得改动这条弧的容量后能恰有为C的流? 题目分析:先找出最大流,如果最大流不比C小,那么一定存在一条恰为C的流.否则,找出最 ...

  8. UVA 820 --- POJ 1273 最大流

    找了好久这两个的区别...UVA820 WA了 好多次.不过以后就做模板了,可以求任意两点之间的最大流. UVA 是无向图,因此可能有重边,POJ 1273是有向图,而且是单源点求最大流,因此改模板的 ...

  9. Risk UVA - 12264 拆点法+最大流+二分 最少流量的节点流量尽量多。

    /** 题目:Risk UVA - 12264 链接:https://vjudge.net/problem/UVA-12264 题意:给n个点的无权无向图(n<=100),每个点有一个非负数ai ...

随机推荐

  1. javascript 内置日期转换方法

    var d = new Date(); console.log(d); // 输出:Mon Nov 04 2013 21:50:33 GMT+0800 (中国标准时间) console.log(d.t ...

  2. Selenium WebDriver的多浏览器测试

    1. IE浏览器,需要配合下载IEDriverSever.exe的驱动程序,目前selenium支持IE9以上. (驱动程序下载链接:https://pan.baidu.com/s/1YpaUsIs1 ...

  3. 使用xmake检测编译器特性支持

    如果我们要写跨平台的c/c++代码,很多时候需要处理由于不同编译器对c/c++各个标准支持力度不同导致的兼容性问题,一般通常的解决办法是:自己在代码中通过宏去判断各个编译器的版本.内置宏.标准库宏._ ...

  4. 九度oj 题目1494:Dota

    题目描述: 大家都知道在dota游戏中,装备是对于英雄来说十分重要的要素. 英雄们不仅可以购买单个的装备,甚至某些特定的装备组合能够合成更强的装备. 为了简化问题,我们将每个装备对于英雄的功能抽象为一 ...

  5. 关于php ‘==’ 与 '===' 遇见的坑

    两个的区别所有PHPer都知道, 今天在遍历 xmlNode时,自己写的代码就碰坑了 想遍历xmlNode为数组 得到的xmlNode为 想要把所有的simpleXmlElement对象都遍历转成数组 ...

  6. [luoguP3355] 骑士共存问题(二分图最大独立集)

    传送门 模型 二分图最大独立集,转化为二分图最大匹配,从而用最大流解决. 实现 首先把棋盘黑白染色,使相邻格子颜色不同. 把所有可用的黑色格子看做二分图X集合中顶点,可用的白色格子看做Y集合顶点. 建 ...

  7. PHP中的验证码类(验证码功能设计之二)

    运行结果: <!--vcode.class.php内容--> <?php class Vcode { private $width; //宽 private $height; //高 ...

  8. Mysql常用语句记录

    建表语句,带自增字段 create table test ( id int auto_increment primary key, name ) not null, password ) not nu ...

  9. docker 查询或获取私有仓库(registry)中的镜像

    docker 查询或获取私有仓库(registry)中的镜像,使用 docker search 192.168.1.8:5000 命令经测试不好使. 解决: 1.获取仓库类的镜像: [root@sha ...

  10. Codeforces 403D: Beautiful Pairs of Numbers(DP)

    题意:转换模型之后,就是1~n个数中选k个,放到一个容量为n的背包中,这个背包还特别神奇,相同的物品摆放的位置不同时,算不同的放法(想象背包空间就是一个长度为n的数组,然后容量为1的物体放一个格子,容 ...