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. Linux 进程及作业管理

    进程简介:  内核的功用:进程管理.文件系统.网络功能.内存管理.驱动程序.安全功能  进程(Process):什么是进程,进程是程序的执行实例,即运行中的程序,同时也是程序的一个副本:程序是放置于磁 ...

  2. 洛谷 P1029 最大公约数和最小公倍数问题

    有两种做法 一种是gcd与lcm相乘后就是两个数的乘积,枚举第一个数,算出第二数,看最大公约数是不是题目给的. 第二种就lcm/gcd的答案为两个互质的数相乘.然后就枚举有多少组互质的数相乘等于lcm ...

  3. Linux5355端口被0.0.0.0监听

    Linux后台有个systemd-resolv进程,占用5355等端口 博主在一次网络安全加固行动中,netstat -anp发现Linux后台有一个被0.0.0.0监听的端口,5355,显示被sys ...

  4. 【codeforces 505D】Mr. Kitayuta's Technology

    [题目链接]:http://codeforces.com/problemset/problem/505/D [题意] 让你构造一张有向图; n个点; 以及所要求的m对联通关系(xi,yi) 即要求这张 ...

  5. SQL SERVER-约束

    NOT NULL - 指示某列不能存储 NULL 值. UNIQUE - 保证某列的每行必须有唯一的值. PRIMARY KEY - NOT NULL 和 UNIQUE 的结合.确保某列(或两个列多个 ...

  6. android开发面试题

    找了将近两个星期的工作,面试了5家公司,罗列一下笔试或者面试时的问题,祝大家好运 1,handler机制 答:handler执行机制:1).在主线程中创建handler 2).子线程中借助主线程的ha ...

  7. Sybase数据库工具DbVisualizer乱码问题

    使用DbVisualizer来操作sybase数据库的时候,会出现乱码问题,中文变成  '口口'. 解决的方法例如以下: 将这三个字体都改成 "宋体"  或者改成 "PM ...

  8. Android-Universal-Image-Loader学习笔记(3)--内存缓存

    前面的两篇博客写了文件缓存.如今说说Android-Universal-Image-Loader的内存缓存.该内存缓存涉及到的类如图所看到的 这些类的继承关系例如以下图所看到的: 如同文件缓存一样,内 ...

  9. hunnu11544:小明的烦恼——找字符串

    Problem description   小明是个非常优秀的同学.他除了特别公正外,他也非常细心,当然老师肯定也知道,这不,老师又有事情找他帮忙了.老师每周都会给他一个字符串A.然后问小明" ...

  10. 如何编译dotnet core

    1.git clone源码 2.init-tools.cmd 3. Error: DIA SDK is missing at "C:\Program Files (x86)\Microsof ...