Tricks Device

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 0    Accepted Submission(s): 0

Problem Description
Innocent Wu follows Dumb Zhang into a ancient tomb. Innocent Wu’s at the entrance of the tomb while Dumb Zhang’s at the end of it. The tomb is made up of many chambers, the total number is N. And there are M channels connecting the chambers. Innocent Wu wants to catch up Dumb Zhang to find out the answers of some questions, however, it’s Dumb Zhang’s intention to keep Innocent Wu in the dark, to do which he has to stop Innocent Wu from getting him. Only via the original shortest ways from the entrance to the end of the tomb costs the minimum time, and that’s the only chance Innocent Wu can catch Dumb Zhang.
Unfortunately, Dumb Zhang masters the art of becoming invisible(奇门遁甲) and tricks devices of this tomb, he can cut off the connections between chambers by using them. Dumb Zhang wanders how many channels at least he has to cut to stop Innocent Wu. And Innocent Wu wants to know after how many channels at most Dumb Zhang cut off Innocent Wu still has the chance to catch Dumb Zhang.
 
Input
There are multiple test cases. Please process till EOF.
For each case,the first line must includes two integers, N(<=2000), M(<=60000). N is the total number of the chambers, M is the total number of the channels.
In the following M lines, every line must includes three numbers, and use ai、bi、li as channel i connecting chamber ai and bi(1<=ai,bi<=n), it costs li(0<li<=100) minute to pass channel i.
The entrance of the tomb is at the chamber one, the end of tomb is at the chamber N.
 
Output
Output two numbers to stand for the answers of Dumb Zhang and Innocent Wu’s questions.
 
Sample Input
8 9
1 2 2
2 3 2
2 4 1
3 5 3
4 5 4
5 8 1
1 6 2
6 7 5
7 8 1
 
Sample Output
2 6
 
解题:最短路+最小割
 
先把所有的最短路提取到另一份图中,然后看看最少经过几条边(可以用dp优化,或者标记已经访问的边来加速)可以由终点到起点
m-减去最少的可经过的边 即可删除的边
 
然后再对刚才提取的图 求最小割,最小割即为最少删除几条边,可以使得最短路变长
 
需要注意重边的影响
 
 
 #include <bits/stdc++.h>
#define pii pair<int,int>
using namespace std;
const int maxn = ;
const int INF = 0x3f3f3f3f;
struct arc {
int to,w,next,id;
arc(int x = ,int y = ,int z = -) {
to = x;
w = y;
next = z;
}
} e[maxn];
int d[maxn],tot,S,T,head[maxn],cur[maxn];
vector< pii >g[maxn];
void add(int u,int v,int wa,int wb,int id = ) {
e[tot] = arc(v,wa,head[u]);
e[tot].id = id;
head[u] = tot++;
e[tot] = arc(u,wb,head[v]);
e[tot].id = id;
head[v] = tot++;
}
bool done[maxn];
priority_queue< pii,vector< pii >,greater< pii > >q;
void dijkstra() {
while(!q.empty()) q.pop();
memset(d,0x3f,sizeof d);
d[S] = ;
memset(done,false,sizeof done);
q.push(pii(d[S],S));
while(!q.empty()) {
int u = q.top().second;
q.pop();
if(done[u]) continue;
done[u] = true;
for(int i = head[u]; ~i; i = e[i].next) {
if(d[e[i].to] > d[u] + e[i].w) {
d[e[i].to] = d[u] + e[i].w;
g[e[i].to].clear();
g[e[i].to].push_back(pii(u,e[i].id));
q.push(pii(d[e[i].to],e[i].to));
} else if(d[e[i].to] == d[u]+e[i].w) {
g[e[i].to].push_back(pii(u,e[i].id));
q.push(pii(d[e[i].to],e[i].to));
}
}
}
}
int minstep;
void dfs(int u,int dep,int fa) {
if(u == S) {
minstep = min(dep,minstep);
return;
}
for(int i = g[u].size()-; i >= ; --i) {
if(g[u][i].first == fa) continue;
dfs(g[u][i].first,dep+,u);
bool flag = true;
for(int j = head[g[u][i].first]; flag && ~j; j = e[j].next) {
if(e[j].id == g[u][i].second) flag = false;
}
if(flag) {
add(g[u][i].first,u,,,g[u][i].second);
//cout<<g[u][i]<<" *** "<<u<<endl;
}
}
}
bool bfs() {
queue<int>q;
memset(d,-,sizeof d);
d[S] = ;
q.push(S);
while(!q.empty()) {
int u = q.front();
q.pop();
for(int i = head[u]; ~i; i = e[i].next) {
if(e[i].w && d[e[i].to] == -) {
d[e[i].to] = d[u] + ;
q.push(e[i].to);
}
}
}
return d[T] > -;
}
int dfs(int u,int low) {
if(u == T) return low;
int tmp = ,a;
for(int &i = cur[u]; ~i; i = e[i].next) {
if(e[i].w &&d[e[i].to] == d[u]+&&(a=dfs(e[i].to,min(e[i].w,low)))) {
e[i].w -= a;
e[i^].w += a;
low -= a;
tmp += a;
if(!low) break;
}
}
if(!tmp) d[u] = -;
return tmp;
}
int dinic() {
int ret = ;
while(bfs()) {
memcpy(cur,head,sizeof head);
ret += dfs(S,INF);
}
return ret;
}
int main() {
int n,m,u,v,w;
while(~scanf("%d%d",&n,&m)) {
for(int i = tot = ; i < maxn; ++i) {
g[i].clear();
head[i] = -;
}
for(int i = ; i < m; ++i) {
scanf("%d%d%d",&u,&v,&w);
add(u,v,w,w,i);
}
S = ;
T = n;
dijkstra();
minstep = INT_MAX;
memset(head,-,sizeof head);
tot = ;
dfs(T,,-);
int by = m-minstep;
int ax = dinic();
printf("%d %d\n",ax,by);
}
return ;
}

重新写了下,思路更清楚些

 #include <bits/stdc++.h>
using namespace std;
using PII = pair<int,int>;
const int maxn = ;
const int INF = 0x3f3f3f3f;
struct arc {
int to,w,next;
arc(int x = ,int y = ,int z = -) {
to = x;
w = y;
next = z;
}
} e[];
int head[maxn],hd[maxn],tot,S,T,n,m;
int gap[maxn],d[maxn];
bool done[maxn];
void add(int head[maxn],int u,int v,int wa,int wb) {
e[tot] = arc(v,wa,head[u]);
head[u] = tot++;
e[tot] = arc(u,wb,head[v]);
head[v] = tot++;
}
void dijkstra() {
memset(d,0x3f,sizeof d);
memset(done,false,sizeof done);
priority_queue<PII,vector<PII>,greater<PII>>q;
d[S] = ;
q.push(PII(,S));
while(!q.empty()) {
int u = q.top().second;
q.pop();
if(done[u]) continue;
done[u] = true;
for(int i = hd[u]; ~i; i = e[i].next) {
if(d[e[i].to] > d[u] + e[i].w) {
d[e[i].to] = d[u] + e[i].w;
q.push(PII(d[e[i].to],e[i].to));
}
}
}
}
void build() {
for(int i = ; i <= n; ++i) {
for(int j = hd[i]; ~j; j = e[j].next) {
if(d[e[j].to] == d[i] + e[j].w)
add(head,i,e[j].to,,);
}
}
}
int bfs() {
memset(gap,,sizeof gap);
memset(d,-,sizeof d);
queue<int>q;
d[T] = ;
q.push(T);
while(!q.empty()) {
int u = q.front();
q.pop();
++gap[d[u]];
for(int i = head[u]; ~i; i = e[i].next) {
if(d[e[i].to] == -) {
d[e[i].to] = d[u] + ;
q.push(e[i].to);
}
}
}
return d[S];
}
int dfs(int u,int low) {
if(u == T) return low;
int tmp = ,minH = n - ;
for(int i = head[u]; ~i; i = e[i].next) {
if(e[i].w) {
if(d[e[i].to] + == d[u]) {
int a = dfs(e[i].to,min(e[i].w,low));
e[i].w -= a;
e[i^].w += a;
tmp += a;
low -= a;
if(!low) break;
if(d[S] >= n) return tmp;
}
if(e[i].w) minH = min(minH,d[e[i].to]);
}
}
if(!tmp) {
if(--gap[d[u]] == ) d[S] = n;
++gap[d[u] = minH + ];
}
return tmp;
}
int sap(int ret = ) {
while(d[S] < n) ret += dfs(S,INF);
return ret;
}
int main() {
int u,v,w;
while(~scanf("%d%d",&n,&m)) {
memset(head,-,sizeof head);
memset(hd,-,sizeof hd);
for(int i = tot = ; i < m; ++i) {
scanf("%d%d%d",&u,&v,&w);
add(hd,u,v,w,w);
}
S = ;
T = n;
dijkstra();
build();
int y = m - bfs(),x = sap();
printf("%d %d\n",x,y);
}
return ;
}

SPFA貌似更快些,这图稀疏

 #include <bits/stdc++.h>
using namespace std;
using PII = pair<int,int>;
const int maxn = ;
const int INF = 0x3f3f3f3f;
struct arc {
int to,w,next;
arc(int x = ,int y = ,int z = -) {
to = x;
w = y;
next = z;
}
} e[];
int head[maxn],hd[maxn],tot,S,T,n,m;
int gap[maxn],d[maxn];
bool in[maxn] = {};
void add(int head[maxn],int u,int v,int wa,int wb) {
e[tot] = arc(v,wa,head[u]);
head[u] = tot++;
e[tot] = arc(u,wb,head[v]);
head[v] = tot++;
}
void dijkstra() {
memset(d,0x3f,sizeof d);
queue<int>q;
d[S] = ;
q.push(S);
while(!q.empty()){
int u = q.front();
q.pop();
in[u] = false;
for(int i = hd[u]; ~i; i = e[i].next){
if(d[e[i].to] > d[u] + e[i].w){
d[e[i].to] = d[u] + e[i].w;
if(!in[e[i].to]){
in[e[i].to] = true;
q.push(e[i].to);
}
}
}
}
}
void build() {
for(int i = ; i <= n; ++i) {
for(int j = hd[i]; ~j; j = e[j].next) {
if(d[e[j].to] == d[i] + e[j].w)
add(head,i,e[j].to,,);
}
}
}
int bfs() {
memset(gap,,sizeof gap);
memset(d,-,sizeof d);
queue<int>q;
d[T] = ;
q.push(T);
while(!q.empty()) {
int u = q.front();
q.pop();
++gap[d[u]];
for(int i = head[u]; ~i; i = e[i].next) {
if(d[e[i].to] == -) {
d[e[i].to] = d[u] + ;
q.push(e[i].to);
}
}
}
return d[S];
}
int dfs(int u,int low) {
if(u == T) return low;
int tmp = ,minH = n - ;
for(int i = head[u]; ~i; i = e[i].next) {
if(e[i].w) {
if(d[e[i].to] + == d[u]) {
int a = dfs(e[i].to,min(e[i].w,low));
e[i].w -= a;
e[i^].w += a;
tmp += a;
low -= a;
if(!low) break;
if(d[S] >= n) return tmp;
}
if(e[i].w) minH = min(minH,d[e[i].to]);
}
}
if(!tmp) {
if(--gap[d[u]] == ) d[S] = n;
++gap[d[u] = minH + ];
}
return tmp;
}
int sap(int ret = ) {
while(d[S] < n) ret += dfs(S,INF);
return ret;
}
int main() {
int u,v,w;
while(~scanf("%d%d",&n,&m)) {
memset(head,-,sizeof head);
memset(hd,-,sizeof hd);
for(int i = tot = ; i < m; ++i) {
scanf("%d%d%d",&u,&v,&w);
add(hd,u,v,w,w);
}
S = ;
T = n;
dijkstra();
build();
int y = m - bfs(),x = sap();
printf("%d %d\n",x,y);
}
return ;
}

2015 Multi-University Training Contest 1 Tricks Device的更多相关文章

  1. HDU5294 Tricks Device(最大流+SPFA) 2015 Multi-University Training Contest 1

    Tricks Device Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) To ...

  2. 2015 Multi-University Training Contest 1(7/12)

    2015 Multi-University Training Contest 1 A.OO's Sequence 计算每个数的贡献 找出第\(i\)个数左边最靠右的因子位置\(lp\)和右边最靠左的因 ...

  3. HDU 5294 Tricks Device(多校2015 最大流+最短路啊)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 Problem Description Innocent Wu follows Dumb Zha ...

  4. 2015 Multi-University Training Contest 8 hdu 5390 tree

    tree Time Limit: 8000ms Memory Limit: 262144KB This problem will be judged on HDU. Original ID: 5390 ...

  5. 2015 UESTC Winter Training #8【The 2011 Rocky Mountain Regional Contest】

    2015 UESTC Winter Training #8 The 2011 Rocky Mountain Regional Contest Regionals 2011 >> North ...

  6. 2015 UESTC Winter Training #7【2010-2011 Petrozavodsk Winter Training Camp, Saratov State U Contest】

    2015 UESTC Winter Training #7 2010-2011 Petrozavodsk Winter Training Camp, Saratov State U Contest 据 ...

  7. Root(hdu5777+扩展欧几里得+原根)2015 Multi-University Training Contest 7

    Root Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Su ...

  8. 2015 Multi-University Training Contest 6 solutions BY ZJU(部分解题报告)

    官方解题报告:http://bestcoder.hdu.edu.cn/blog/2015-multi-university-training-contest-6-solutions-by-zju/ 表 ...

  9. HDU 5360 Hiking(优先队列)2015 Multi-University Training Contest 6

    Hiking Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total S ...

随机推荐

  1. [CTSC1999][网络流24题]补丁VS错误

    题目:洛谷P2761.vijos P1019.codevs1239.codevs2218. 题目大意:有n个错误,m个不同的补丁. 对于一个补丁,有两个不同的字符串描述.具体如下: 如果当前错误包含第 ...

  2. hdu5791 TWO

    hdu5791 TWO 题意 给你两个数串 问你两个数串有多少子串一致 子串不一定是连续的 解法 我们设 \(dp[i][j]\) 表示A串匹配到 i 位,B串匹配到 j 位,一致的子串数.那么我们有 ...

  3. Memcached的实战笔记

    官网:http://memcached.org/ 优秀Blogs: http://blog.csdn.net/jingqiang521/article/details/48345021 开启telne ...

  4. AsyncTask 简要介绍

    当Android的UI线程超过5s未响应时,系统会引发ANR(Application Not Responding)异常,所以一般不在UI线程中执行耗时任务.一般是在其他线程中处理耗时任务,然后及时更 ...

  5. reac实现控制输入框字符长度

    reac实现控制输入框字符长度 代码思路:

  6. 【codeforces 794A】Bank Robbery

    [题目链接]:http://codeforces.com/contest/794/problem/A [题意] 每个位置上可能有物品(>=1)或是没物品 你一开始在某一个位置b; 然后你最左可以 ...

  7. Python 获取Google+特定用户最新动态

    CODE: #!/usr/bin/python # -*- coding: utf-8 -*- ''' Created on 2014-8-28 @author: guaguastd @name: l ...

  8. world 替换+正则表达式命令

    打开替换命令,点击“更多”,勾选上“通配符”,正则表达式才会起作用

  9. Redis和Memcache和MongoDB简介及区别分析(整理)

    Redis和Memcache 一.Redis简介 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年 ...

  10. OC冒泡排序算法

    面试的时候很多公司会要求写一个冒泡排序算法,于是用OC写了一个,代码如下所示 需要注意的事项:oc数组只能存放oc对象,因此遍历数组输出的时候,记得通过NSString对象转换成intValue #i ...