题意是有n座城市,n号城市不想让1号城市可达n号,每条道路有一条毁坏的代价,1号还可以修一条不能毁坏的道路,求n号城市所需的最小代价最大是多少。

毁坏的最小代价就直接求一遍最大流,就是最小割了。而可以修一条不能毁坏的路,需要枚举的这些边就是源集中的点到汇集中的点,我之前的做法是直接找出所有的割边,再枚举每一条割边,在这两个点上加一个流量为无穷大的边再去求最大流,实际上这样连样例的第二个数据都过不了,因为图不保证是连通的,那就有一些源集中的点和汇集中的点本来就不联通,就不存在这样的割边了。发现这个错误后,我就在没有联通的所有边中加了一条cap为0的边,想弥补上面的bug,但是这样的话超时了。奇怪的是,我没有加那些cap为0的点的时候也是超时而不是wa。

所以就找出所有的源点,找出所有的汇点,去除1和n后枚举这些边在原来的基础上去跑最大流,得出来的意义就是如果修的是这条路,所需要的额外的代价。

我自己的代码不知道为什么过不了,可能是模板的问题?

贴两个代码吧,前面是自己的,后面是别人的。

 #include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#define LL long long
#define eps 1e-8
#define INF 0x3f3f3f3f
#define MAXN 105
#define OPEN_FILE
using namespace std;
int S;
struct Edge{
int from, to, cap, flow;
//Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f){};
};
vector<Edge> cutset;
bool comp(const Edge& a, const Edge& b){
return (a.from < b.from || (a.from == b.from && a.to < b.to));
}
struct Dinic{
int n, m, i, s, t;
Edge e;
vector<Edge> edges;
vector<int> G[MAXN];
int d[MAXN], cur[MAXN];
// bool vis[MAXN];
int Q[MAXN * ]; void init(int n){
this->n = n;
for (i = ; i <= n; i++){
G[i].clear();
}
edges.clear();
}
void AddEdge(int from, int to, int cap){
edges.push_back(Edge{ from, to, cap, });
edges.push_back(Edge{ to, from, , });
m = edges.size();
G[from].push_back(m - );
G[to].push_back(m - );
}
bool BFS(){
// memset(vis, 0, sizeof(vis));
int head = , tail = ;
Q[head] = s;
memset(d, , sizeof(d));
d[s] = ;
S = ;
while (head <= tail){
int x = Q[head++];
for (i = ; i < G[x].size(); i++){
Edge& e = edges[G[x][i]];
if (d[e.to] == && e.cap > e.flow){
d[e.to] = d[x] + ;
Q[++tail] = e.to;
S++;
}
}
}
if (d[t] == ){
return false;
}
else{
return true;
}
}
int DFS(int x, int a){
if (x == t || a == ) return a;
int flow = , f;
for (int& i = cur[x]; i < G[x].size(); i++){
Edge& e = edges[G[x][i]];
if (d[x] + == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > ){
e.flow += f;
edges[G[x][i] ^ ].flow -= f;
flow += f;
a -= f;
if (a == ) break;
}
}
return flow;
}
int MaxFlow(int s, int t, int need){
int flow = ;
this->s = s;
this->t = t;
while (BFS()){
memset(cur, , sizeof(cur));
flow += DFS(s, INF);
if (flow > need) return flow;
}
return flow;
}
};
int n, m;
Dinic p, q;
int RIGHT[MAXN];
int main()
{
#ifdef OPEN_FILE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif // OPEN_FILE
int T;
scanf("%d", &T);
for (int cas = ; cas <= T; cas++){
scanf("%d%d", &n, &m);
p.init(n);
int x, y, z;
// memset(conn, 0, sizeof(conn));
for (int i = ; i <= m; i++){
scanf("%d%d%d", &x, &y, &z);
p.AddEdge(x, y, z);
// conn[x][y] = true;
//conn[y][x] = true;
}
//int res = p.MaxFlow(1, n, INF);
//p.AddEdge(2, 3, INF);
//q = p;
int res = p.MaxFlow(, n, INF);
int cnt = ;
// memset(isR, 0, sizeof(isR));
for (int i = ; i < n; i++){
if (p.d[i] == ){
RIGHT[cnt++] = i;
}
}
cnt--;
int ans = ;
for (int i = ; i <= S; i++){
if (p.Q[i] == || p.Q[i] == n) continue;
for (int j = ; j <= cnt; j++){
q = p;
q.AddEdge(p.Q[i], RIGHT[j], INF);
int o = q.MaxFlow(, n, INF);
ans = max(ans, o);
}
}
// int ans = 0;
// for (int i = 0; i < cutset.size(); i++){
// q = p;
// q.AddEdge(cutset[i].from, cutset[i].to, INF);
// int o = q.MaxFlow(1, n, INF);
// ans = max(ans, o);
// }
printf("%d\n", ans + res);
// printf("%d\n", p.MaxFlow(1, n, INF));
}
}
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<cstdio>
#include<string>
#include <algorithm>
using namespace std;
const int maxn = ;
//const int maxm=300006;
const int inf = << ; struct node
{
int v, next;
int val;
};
int topset;
struct dinic{
node s[maxn*maxn * ]; int level[maxn];//顶点的层次
int p[maxn];
int que[maxn * ];//BFS中用于遍历的顶点,DFS求增广中记录边
int out[ * maxn];//DFS用于几乎定点的分支
int ind; int cop_poit[maxn];
node cop_mp[maxn*maxn * ]; void init()
{
ind = ;
memset(p, -, sizeof(p));
} inline void insert(int x, int y, int z)
{
s[ind].v = y;
s[ind].val = z;
s[ind].next = p[x];
p[x] = ind++;
s[ind].v = x;
s[ind].val = ;
s[ind].next = p[y];
p[y] = ind++;
} int max_flow(int n, int source, int sink)
{
int ret = ;
int h = , r = ;
while ()//DFS
{
int i;
for (i = ; i <= n; ++i)
level[i] = ;
h = , r = ;
level[source] = ;
que[] = source;
while (h <= r)//BFS
{
int t = que[h++];
for (i = p[t]; i != -; i = s[i].next)
{
if (s[i].val&&level[s[i].v] == )
{
level[s[i].v] = level[t] + ;
que[++r] = s[i].v;
}
}
}
topset = r;//记录原点的集合个数 if (level[sink] == )break;//找不到汇点
for (i = ; i <= n; ++i)
out[i] = p[i]; int q = -;
while ()
{
if (q < )
{
int cur = out[source];
for (; cur != -; cur = s[cur].next)
{
if (s[cur].val&&out[s[cur].v] != - && level[s[cur].v] == )
{
break;
}
}
if (cur >= )
{
que[++q] = cur;
out[source] = s[cur].next;
}
else
{
break;
}
} int u = s[que[q]].v; if (u == sink)//一条增广路
{
int dd = inf;
int index = -;
for (i = ; i <= q; i++)
{
if (dd > s[que[i]].val)
{
dd = s[que[i]].val;
index = i;
}
}
ret += dd;
//cout<<ret<<endl;
for (i = ; i <= q; i++)
{
s[que[i]].val -= dd;
s[que[i] ^ ].val += dd;
}
for (i = ; i <= q; i++)
{
if (s[que[i]].val == )
{
q = index - ;
break;
}
}
}
else
{
long cur = out[u];
for (; cur != -; cur = s[cur].next)
{
if (s[cur].val&&out[s[cur].v] != - && level[u] + == level[s[cur].v])
{
break;
}
}
if (cur != -)
{
que[++q] = cur;
out[u] = s[cur].next;
}
else
{
out[u] = -;
q--;
}
}
}
}
return ret;
}
}; int m, n;
int q[maxn * ];
dinic x, y;
int main()
{
freopen("in.txt", "r", stdin);
int cas;
cin >> cas;
int huijie[maxn];
while (cas--)
{
x.init();
scanf("%d%d", &n, &m);
for (int i = ; i < m; i++)
{
long from, to, cost;
scanf("%d %d %d", &from, &to, &cost);
x.insert(from, to, cost);
}
long Start, End;
Start = ; End = n;
int tmp = x.max_flow(n, Start, End);//计算一次最大流(最小割) y = x; int ans = ;
int r = ; for (int j = ; j < n; j++)//求出汇集---因为bfs找不到一条增广路时,qu中就是原集,剩下来就是汇集,也可以是leve数组便利不到的顶点
{
if (x.level[j] == )
huijie[r++] = j;
} for (int i = ; i <= topset; i++)//枚举两顶点
{
if (x.que[i] == || x.que[i] == n) continue;
for (int j = ; j < r; j++)
{
y = x;
y.insert(x.que[i], huijie[j], inf);//加边
int g = y.max_flow(n, , n);//格外的代价
ans = max(ans, g);
}
}
printf("%d\n", ans + tmp);
}
return ;
}

HDU 2435 There is a war Dinic 最小割的更多相关文章

  1. HDU 2435 There is a war (网络流-最小割)

    There is a war Problem Description       There is a sea.       There are N islands in the sea.       ...

  2. HDU 2435 There is a war

    There is a war Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ...

  3. POJ 1815 Friendship (Dinic 最小割)

    Friendship Time Limit: 2000MS   Memory Limit: 20000K Total Submissions: 8025   Accepted: 2224 Descri ...

  4. HDU 2676 Network Wars 01分数规划,最小割 难度:4

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1676 对顶点i,j,起点s=1,终点t=n,可以认为题意要求一组01矩阵use ...

  5. HDU 6214 Smallest Minimum Cut(最少边最小割)

    Problem Description Consider a network G=(V,E) with source s and sink t. An s-t cut is a partition o ...

  6. hdu 1569 &1565 (二分图带权最大独立集 - 最小割应用)

    要选出一些点,这些点之间没有相邻边且要求权值之和最大,求这个权值 分析:二分图带权最大独立集. 用最大流最小割定理求解.其建图思路是:将所有格点编号,奇数视作X部,偶数视作Y部,建立源点S和汇点T, ...

  7. HDU 6214 Smallest Minimum Cut 【网络流最小割+ 二种方法只能一种有效+hdu 3987原题】

    Problem Description Consider a network G=(V,E) with source s and sink t . An s-t cut is a partition ...

  8. HDU - 5457 Hold Your Hand (Trie + 最小割)

    Hold Your Hand Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)T ...

  9. 【hdu 4859】海岸线(图论--网络流最小割)

    题意:有一个区域,有'.'的陆地,'D'的深海域,'E'的浅海域.其中浅海域可以填充为陆地.这里的陆地区域不联通,并且整个地图都处在海洋之中.问填充一定浅海域之后所有岛屿的最长的海岸线之和. 解法:最 ...

随机推荐

  1. java几种远程服务调用协议的比较

    原文地址:http://www.cnblogs.com/jifeng/archive/2011/07/20/2111183.html 一.综述 本文比较了RMI,Hessian,Burlap,Http ...

  2. vue-cli 打包 使用 history模式 的后端配置

    apache的配置 这是windows下的 在httpd-vhosts.conf文件中把目录指向项目index.html文件所在的位置 # Virtual Hosts # <VirtualHos ...

  3. (51) magento集成增加到款通知

    这篇主要讲述如何二开增加自己的功能,我没有继承方式二开,习惯是不好的,直接改了原来的模块. 达到效果就这样,当在网站支付成功,会同步到ERP系统中.下面来讲述实现过程 建立文件 payment_not ...

  4. ztree实现根节点右击事件,显示添加删除

    需求,右击树节点,出现编辑和删除的提示框 1:在setting 配置里面,给callback设置,右击事件onRightClick: 2:写一个函数onRightClick function onRi ...

  5. 按shift键调出命令行的脚本

    打开Notepad++,粘贴以下命令,并将文件命名为opencmdhere.reg(注意:文件编码格式为UCS-2 Little Endian,否则会导致中文乱码),再双击打开即可 Windows R ...

  6. 基于SpringMVC+Bootstrap+DataTables实现表格服务端分页、模糊查询

    前言 基于SpringMVC+Bootstrap+DataTables实现数据表格服务端分页.模糊查询(非DataTables Search),页面异步刷新. 说明:sp:message标签是使用了S ...

  7. URAL - 1243 - Divorce of the Seven Dwarfs (大数取模)

    1243. Divorce of the Seven Dwarfs Time limit: 1.0 second Memory limit: 64 MB After the Snow White wi ...

  8. ACM POJ 1146 ID Codes

    题目大意:输入一个字符串.输出它的下一个字典序排列. 字典序算法思想: 1.从右向左寻找字符串找出第一个a[i]<a[i+1]的位置i; 2.从右向左找出第一个大于a[i]的元素a[j]; 3. ...

  9. [Python]Use Flask-Admin with PostgreSQL

    This code recipe gives you an idea of how to use Flask-Admin with postgresql database. from flask im ...

  10. C语言之文件操作04——输入矩阵a,b,求乘积c,并打印a,b,c到文件

    //文件与数组结合 /* ================================================================= 题目:输入矩阵a,b,求乘积c,并打印a, ...