4663: Hack

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 69  Solved: 26

Description

由于 FZYZ 教学区禁止使用手机,所以如何在一个课间通知到人就成了一个很大的问题。所幸,在不知道被信息传
递不及时坑了多少次之后,小叶子(@97littleleaf11)完美地解决了这个问题。小叶子组建了一张关系网,每一个
人是这张关系网上的一个节点(节点编号为[0,n-1]),两个人之间的通讯关系就是这张网上的一条有向边(一条 u->
v 的边意味着信息可以从u 传递到 v)。小叶子是 0 号节点,也是信息的发出者,n+e 是 n-1 号节点,在这个问
题中,他就是信息的接受者。一条信息从小叶子出发,可以沿着任意的边传递,最终传递给 n+e。在这个过程中,
一个人(包括小叶子和 n+e)可以经过多次,一条边也可以经过多次。经过多年的观察,小叶子发现这张关系网的每
一条边都是有可能被hack 的!当然每条边 hack 的代价是不一样的。所以,小叶子想要评价这个关系网的安全程
度。试想你要入侵这一张关系网,那么你只能事先选择一些边,将这些边hack 掉。如果一条边被 hack 了,就意
味着当信息从这条边传递的时候就会被截获。当然 n+e 也是非常厉害的!如果一条信息在传递过程中被截获两次
及以上,那么 n+e 就能用强大的智商定位出你的位置,那么这一次入侵就必然会失败。当然,如果 n+e 接收到了
消息,但是这条消息没有被截获,那么这次入侵也就是失败的。更精确地说,一次成功的入侵要满足以下条件:对
于任意一种可能的传递信息的方式(对应着一条从 0 到 n-1 的路径),必须经过恰好一次被hack 的边。一次入侵
的代价就是你选择 hack 掉的边的代价和。小叶子想要知道,如果你拥有 n+e 这样超神的智商,而你又想最小化
代价,那么你入侵的代价会是多少呢?

Input

第一行 n,m。表示点数及边数
接下来 m 行,每行三个整数 u,v,w,表示一条从 u 到 v 的代价为 w 的边。
2<=n<=100,m<=2500,1<=w<=10^9,0<=u,v<n,保证存在至少一条从0到n-1的路径。

Output

输出一行,表示答案。,如果不存在合法的入侵方案,那么输出-1.

Sample Input

6 7
0 1 5
0 2 5
1 3 1
2 4 1
4 1 1
3 5 5
4 5 5

Sample Output

6
//hack 掉 0->1,2->4 这两条边

HINT

Source

【分析】

  其实反向边建INF的想法有考虑过。但是不会证。很迷人。。。

  送个迷人的图:

  

  就是建了inf反向边,就不会同一路径的割了,因为并不会更好。。

  然后要注意删掉st到不了的点,不然会有这样迷人的情况:

  

  st本来不会经过a到ed,但现在这样建INF,就一定要割掉一些边断掉它了。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
#define Maxn 110
#define Maxm 2600
#define LL long long
const LL INF=(LL)*(LL)1e9; LL mymin(LL x,LL y) {return x<y?x:y;} struct node{int x,y,o,next;LL f;bool p;}t[Maxm*];
bool vis[Maxn];
int first[Maxn],len; void ins(int x,int y,LL f)
{
t[++len].x=x;t[len].y=y;t[len].f=f;
t[len].next=first[x];first[x]=len;t[len].o=len+;
t[++len].x=y;t[len].y=x;t[len].f=INF;
t[len].next=first[y];first[y]=len;t[len].o=len-;
t[len-].p=t[len].p=;
} void dfs(int x)
{
vis[x]=;
for(int i=first[x];i;i=t[i].next)
{
if(i%==) continue;
int y=t[i].y;
if(!vis[y]) dfs(y);
}
} int st,ed;
int dis[Maxn];
queue<int > q;
bool bfs()
{
for(int i=;i<=ed;i++) dis[i]=-;
while(!q.empty()) q.pop();
dis[st]=;q.push(st);
while(!q.empty())
{
int x=q.front();
for(int i=first[x];i;i=t[i].next) if(t[i].p&&t[i].f>)
{
int y=t[i].y;
if(!vis[y]) continue;
if(dis[y]==-)
{
dis[y]=dis[x]+;
q.push(y);
}
}
q.pop();
}
if(dis[ed]==-) return ;
return ;
} LL ffind(int x,LL flow)
{
if(x==ed) return flow;
LL now=;
for(int i=first[x];i;i=t[i].next) if(t[i].p&&t[i].f>)
{
int y=t[i].y;
if(dis[y]==dis[x]+)
{
LL a=ffind(y,mymin(flow-now,t[i].f));
t[i].f-=a;
t[t[i].o].f+=a;
now+=a;
}
if(now==flow) break;
}
if(now==) dis[x]=-;
return now;
} void output()
{
for(int i=;i<=len;i++) if(t[i].p)
{
printf("%d -> %d %d\n",t[i].x,t[i].y,t[i].f);
}printf("\n");
} LL ans=;
void max_flow()
{
while(bfs())
{
ans+=ffind(st,INF);
if(ans>=INF) break;
}
} int main()
{
int n,m;
scanf("%d%d",&n,&m);
len=;
memset(first,,sizeof(first));
for(int i=;i<=m;i++)
{
int x,y;LL f;
scanf("%d%d%lld",&x,&y,&f);
x++;y++;
ins(x,y,f);
}
for(int i=;i<=n;i++) vis[i]=;vis[]=;
dfs();
for(int i=;i<=len;i+=) if(vis[t[i].x]==) t[i].p=t[t[i].o].p=;
st=;ed=n;
// output();
max_flow();
if(ans>=INF) printf("-1\n");
else printf("%lld\n",ans);
return ;
}

2017-03-31 08:26:56

【BZOJ 4663】 (最小割)的更多相关文章

  1. BZOJ 1412 & 最小割

    什么时候ZJ省选再现一次这么良心的题吧... 题意: 在一个染色的格子画分割线,使其不想连,求最少的线段 SOL: 裸裸的最小割.题目要求两种颜色不想连,我们把他分到两个集合,也就是把所有相连的边切断 ...

  2. BZOJ 1797 最小割

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1797 题意:给出一个有向图,每条边有流量,给出源点汇点s.t.对于每条边,询问:(1)是 ...

  3. BZOJ 2229 最小割

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2229 题意:给定一个带权无向图.若干询问,每个询问回答有多少点对(s,t)满足s和t的最 ...

  4. bzoj 1497 最小割模型

    我们可以对于消费和盈利的点建立二分图,开始答案为所有的盈利和, 那么源向消费的点连边,流量为消费值,盈利向汇连边,流量为盈利值 中间盈利对应的消费连边,流量为INF,那么我们求这张图的最小割,用 开始 ...

  5. bzoj 1934 最小割

    收获: 1.流量为0的边可以不加入. 2.最小割方案要与决策方案对应. #include <cstdio> #include <cmath> #include <cstr ...

  6. bzoj 3996 最小割

    公式推出来后想了半天没思路,居然A是01矩阵..... 如果一个问题是求最值,并那么尝试先将所有可能收益加起来,然后矛盾部分能否用最小割表达(本题有两个矛盾,第一个是选还是不选,第二个是i,j有一个不 ...

  7. bzoj 1934最小割

    比较显然的最小割的题,增加节点source,sink,对于所有选1的人我们可以(source,i,1),选0的人我们可以(i,sink,1),然后对于好朋友我们可以连接(i,j,1)(j,i,1),然 ...

  8. bzoj 1497 最小割

    思路:最小割好难想啊,根本想不到.. S -> 用户群 = c[ i ] 基站 -> T = p[ i ] 用户群 -> a[ i ] = inf 用户群 -> b[ i ] ...

  9. BZOJ 1797 最小割(最小割割边唯一性判定)

    问题一:是否存在一个最小代价路径切断方案,其中该道路被切断? 问题二:是否对任何一个最小代价路径切断方案,都有该道路被切断? 现在请你回答这两个问题. 最小割唯一性判定 jcvb: 在残余网络上跑ta ...

  10. BZOJ - 1497 最小割应用

    题意:基站耗费成本,用户获得利益(前提是投入成本),求最大获利 最小割的简单应用,所有可能的收益-(消耗的成本/失去的收益),无穷大边表示冲突,最小割求括号内的范围即可 #include<ios ...

随机推荐

  1. 赶快收藏!16款最流行的 JavaScript 框架

    下面为大家介绍 16款最流行的 JavaScript 框架,赶快收藏! 1. jQuery – Javascript框架 jQuery 是最流行的 JavaScript 框架,它简化了HTML 文档遍 ...

  2. 原创:HTML 头像截取上传 JS+PHP 整合包~

    关于: 关于头像上传这个东西,网上一搜乱七八糟的一堆然而很少很少有自己中意的插件一怒之下就自己写一个... 用法: <!DOCTYPE html> <html lang=" ...

  3. 阿里iconfont引入方法

    原文:iconfont的引入方法   第一步:使用font-face声明字体@font-face {font-family: 'iconfont';src: url('iconfont.eot'); ...

  4. bzoj 2741 可持久化trie

    首先我们设si为前i个数的xor和,那么对于询问区间[i,j]的xor和,就相当于si-1^sj,那么对于这道题的询问我们可以处理处si,然后对于询问[l,r],可以表示为在区间[l-1,r]里找两个 ...

  5. ubuntu永久修改主机名

    1.查看主机名 在Ubuntu系统中,快速查看主机名有多种方法:其一,打开一个GNOME终端窗口,在命令提示符中可以看到主机名,主机名通常位于“@”符号后:其二,在终端窗口中输入命令:hostname ...

  6. tar解压与压缩

    1.解压 tar -zxvf  压缩文件名  -C 指定的目录   (制定的目录必须存在) 2.压缩 tar -czvf  压缩后的文件名   要压缩的文件夹

  7. [001] leap_stage

    [Description] There is a number in each stages that indicates the most stages you can leap up. Now, ...

  8. SilverLight 浏览器出现滚动条

    照网上说的很多解决方案要不得,最后想了下,直接在body上面加 style="overflow:hidden"解决问题,真觉得微软管理混乱,很多它自己的东西都不支持了.

  9. IT行业经典面试技巧及方法思路。

    问题1:为什么从上家公司离职?”能说说原因吗? 首先,作为一个从事招聘的HR,并不认为追问面试者为什么从上一家公司离职是个明智的做法起码不应该在面试一开始就抛出这个问题,一个较为明显的原因是因为这会引 ...

  10. ioctl socket getsockopt

    一 ioctl 函数产生原因: 虽然在文件操作结构体"struct file_operations"中有很多对应的设备操作函数,但是有些命令是实在找不到对应的操作函数.如CD-RO ...