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. 【bzoj 1502】月下柠檬树

    月下柠檬树 题意 求n个圆与他们的公切线的定积分. 解法 求出圆的公切线就可以了. 特别坑的一点 : 最两端的圆,有可能会被其他的圆所包含,所以要重新求一下最左端与最右端. 比较坑的一点 : 精度要设 ...

  2. [读书笔记] R语言实战 (六) 基本图形方法

    1.  条形图 barplot() #载入vcd包 library(vcd) #table函数提取各个维度计数 counts <- table(Arthritis$Improved) count ...

  3. Linux下安装Solr7.5.0,并部署到Tomcat

    收藏地址:https://blog.csdn.net/qq_39135287/article/details/84260724

  4. [WPF] 圆形等待效果

    原文:[WPF] 圆形等待效果 自己做着玩儿的,留着以后用,效果类似下面的 GIF 动画. <Grid Width="35" Height="35"> ...

  5. Linux下MySql数据库常用操作

    1.显示数据库 show databases; 2.选择数据库 use 数据库名; 3.显示数据库中的表 show tables; 4.显示数据表的结构 describe 表名; 5.显示表中记录 S ...

  6. win7创建webdav

    环境 win7+iis 构筑条件 存放路径:c:\Data 访问方式:192.168.x.xxx/webdav 用户名:yx 密码:yx 搭建顺序 1.添加iis.启动->控制面板->程序 ...

  7. HDU 4320 Contest 3

    只需A的全部质因数包含在B中即可. #include <iostream> #include <cstdio> #define LL __int64 #include < ...

  8. video_capture模块分析

    1. 对外接口      VideoCaptureModule     控制接口      VideoCaptureDataCallback Vie中的ViECapturer继承,用于响应抓包数据 2 ...

  9. CodeForces ---596B--Wilbur and Array(贪心模拟)

    Wilbur and Array Time Limit: 2000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Su ...

  10. cximage功能简介

    CxImage是一个可以用于MFC 的C++图像处理类库类,它可以打开,保存,显示,转换各种常见格式的图像文件,比如BMP, JPEG, GIF, PNG, TIFF, MNG, ICO, PCX, ...