HDU 5294--Tricks Device【最小割 && 最短路处理,新建图】

Tricks Device

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 2208    Accepted Submission(s): 584

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

题意:

n个点,m条边,构建有权无向图。

求出删去最少条边数可以使得图没有最短路径,以及删出最多条边使得图仍有最多条路径。

思路:

(1)最短路处理出最短路径图,若dis[v] = dist[u] + w(u,v),则该路在最短路径中。把最短路的边加进最短路径图,边权值为1,在新图求最小割。转化成对立问题,求1
-> N的最大流。

(2)在跑最短路中用side数组记录最短路的最少边数,m - side[ n ]即为解。

最短路处理出最短路径图是本题的难点, 想了好久都没想明白,最后宇哥哥给讲了一下, 还是对spfa的理解不够深入。

最短路处理出最短路径图代码:

//重见图
void getmap(){
    for(int i = 1; i <= n; ++i)//枚举起点
    for(int j = head1[i]; j != -1 ; j = str[j].next){
        NODE E = str[j];
        if(dist[E.v] == dist[i] + E.w)//加上最短路上的边
            addedge(i, E.v, 1);
    }
}

AC代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#define maxn 2000+100
#define maxm 200000+100
#define INF 0x3f3f3f3f
using namespace std;
int m, n;
int head[maxn], cur[maxn], cnt;
int head1[maxn], cnt1;
int dist[maxn], vis[maxn];
int side[maxn];
struct node{
    int u, v, cap, flow, next;
};
node edge[maxm];

struct NODE{
    int u, v, w, next;
};

NODE str[maxm];

void initedge(){
    cnt = 0;
    memset(head, -1, sizeof(head));
}

void initstr(){
    cnt1 = 0;
    memset(head1, -1, sizeof(head1));
}

void addedge(int u, int v, int w){
    node E1 = {u, v, w, 0, head[u]};
    edge[cnt] = E1;
    head[u] = cnt++;
    node E2 = {v, u, 0, 0, head[v]};
    edge[cnt] = E2;
    head[v] = cnt++;
}

void addstr(int u, int v, int w){
    NODE E1 = {u, v, w, head1[u]};
    str[cnt1] = E1;
    head1[u] = cnt1++;
    NODE E2 = {v, u, w, head1[v]};
    str[cnt1] = E2;
    head1[v] = cnt1++;
}

void spfa(){//求出最短路径 + 到达N最少经过的边数,边数存在 side里面
    queue<int>q;
    for(int i = 1; i <= n; ++i){
        vis[i] = 0;
        dist[i] = INF;
        side[i] = 0;
    }
    vis[1] = 1;
    dist[1] = 0;
    q.push(1);
    while(!q.empty()){
        int u = q.front();
        q.pop();
        vis[u] = 0;
        for(int i = head1[u]; i != -1; i = str[i].next){
            int v = str[i].v;
            int w = str[i].w;
            if(dist[v] > dist[u] + w){
                dist[v] = dist[u] + w;
                side[v] = side[u] + 1;
                if(!vis[v]){
                    vis[v] = 1;
                    q.push(v);
                }
            }
            else if(dist[v] == dist[u] + w)
                side[v] = min(side[v], side[u] + 1);
        }
    }
}
//重见图
void getmap(){
    for(int i = 1; i <= n; ++i)//枚举起点
    for(int j = head1[i]; j != -1 ; j = str[j].next){
        NODE E = str[j];
        if(dist[E.v] == dist[i] + E.w)//加上最短路上的边
            addedge(i, E.v, 1);
    }
}

bool BFS(int st, int ed){
    queue<int>q;
    memset(vis, 0, sizeof(vis));
    memset(dist, -1, sizeof(dist));
    vis[st] = 1;
    dist[st] = 0;
    q.push(st);
    while(!q.empty()){
        int u =q.front();
        q.pop();
        for(int i = head[u]; i != -1; i = edge[i].next){
            node E = edge[i];
            if(!vis[E.v] && E.cap > E.flow){
                vis[E.v] = 1;
                dist[E.v] = dist[u] + 1;
                if(E.v == ed) return true;
                q.push(E.v);
            }
        }
    }
    return false;
}

int DFS(int x, int ed, int a){
    if(x == ed || a == 0)
        return a;
    int flow = 0, f;
    for(int &i = cur[x]; i != -1; i = edge[i].next){
        node &E = edge[i];
        if(dist[E.v] == dist[x] + 1 && (f = DFS(E.v, ed, min(a, E.cap - E.flow))) > 0){
            E.flow += f;
            edge[i ^ 1].flow -= f;
            a -= f;
            flow += f;
            if(a == 0) break;
        }
    }
    return flow;
}

int maxflow(int st, int ed){
    int flowsum = 0;
    while(BFS(st, ed)){
        memcpy(cur, head, sizeof(head));
        flowsum += DFS(st, ed, INF);
    }
    return flowsum;
}

int main (){
    while(scanf("%d%d", &n, &m) != EOF){
        initstr();
        for(int i = 1; i <= m; ++i){
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            addstr(u, v, w);
        }
        spfa();
        initedge();
        getmap();
        printf("%d %d\n", maxflow(1, n), m - side[n]);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-09-29 03:09:17

HDU 5294--Tricks Device【最小割 && 最短路处理,新建图】的相关文章

HDU 5294 Tricks Device (最大流+最短路)

题目链接:HDU 5294 Tricks Device 题意:n个点,m条边,并且一个人从1走到n只会走1到n的最短路径,问至少破坏几条边使原图的最短路不存在,最多破坏几条边使原图的最短路劲仍存在 思路: 1.跑一遍最短路,记录下所有最短路径,将这些最短路径的边以(0,1)(流量,容量)加到网络流中,跑一遍最大流 2.记录下的所有最短路径,再加到新的最短路的图中,边权为1,跑一遍最短路,m-最短路 就是答案 注意:有重边的情况 比如: 2 3 1 2 1 1 2 1 1 2 1 ans: 3 2

hdu 5294 Tricks Device(最短路 + 最大流)

hdu 5294 Tricks Device 题目大意:吴邪在古墓中追张起灵,古墓中有很多条路,走每条路都需要一个时间,吴邪只有在最短的时间从古墓的入口到达出口才能追上张起灵.但是张起灵很厉害,他可以使用奇门遁甲使一条路无法通行.现在,问,张起灵最少堵住几条路就可以使吴邪追不上他,以及在吴邪可以追上张起灵的情况下,张起灵最多能堵多少条路. 解题思路:先求出古墓中的最短路(耗时最少的路),再求最短路的同时,记录走最短路要通过哪几条路和走最短路最少通过的路数.最多能堵住的路就是总的路数减去走最短路所

hdu 5294 Tricks Device 最短路建图+最小割

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 Tricks Device Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 375    Accepted Submission(s): 98 Problem Description Innocent Wu follows Dumb Zh

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 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

hdu 5294 Tricks Device(2015多校第一场第7题)最大流+最短路

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 题意:给你n个墓室,m条路径,一个人在1号墓室(起点),另一个人在n号墓室(终点),起点的那个人只有通过最短路径才能追上终点的那个人,而终点的那个人能切断任意路径. 第一问--终点那人要使起点那人不能追上的情况下可以切的最少的路径数,输出最少的路径数 第二问--起点那人能追上终点那人的情况下,终点那人能切断的最多的路径数,输出最多的路径数 思路:要使起点那人无法追上,只要使他的最短路径不存在就

hdu 5294 Tricks Device

求边最少最短路 求最短路构成的边权为1的图的最大流 两个 模板 #include <iostream> #include <stdio.h> #include <math.h> #include <string.h> #include <set> #include <map> #include <queue> #include <vector> #include <string> #include

BZOJ 2007 海拔(平面图最小割-最短路)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2007 题意:给出一个n*n的格子,那么顶点显然有(n+1)*(n+1)个.每两个相邻顶点之间有两条边,这两条边是有向的,边上有权值..左上角为源点,右下角为汇点,求s到t的最小割. 思路:很明显这是一个平面图,将其转化为最 短路.我们将s到t之间连一条边,左下角为新图的源点S,右上角区域为新图的终点T,并且为每个格子编号.由于边是有向的,我们就要分析下这条边应该是哪 个点向哪个点的边.

SPOJ 839 Optimal Marks 最小割 经典 按位建图

胡伯涛论文中的一题,经典建模,由于二进制每一位异或不会相互影响,所以我们把问题转换模型,按位处理. 即已知一些点的标号0/1(还有些可以自己任意改),和一些边,边权定义为两端点标号的异或,要求边权和最小的标号方案. 我们联想到最小割求的是从源到汇容量最小的边权和. 建图: 标号为1的和源点相连,容量INF,标号为0的和汇点相连,容量INF,这些边是不能割掉的(这些点标号已经明确) 原图相连的边,连边,容量为1.(若将此边割掉,则两端点一个为0,一个为1,割为1) 跑完最大流后,在残量网络中dfs

HDU 5294(Tricks Device-最短路最小割)[Template:SPFA]

Tricks Device Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2389    Accepted Submission(s): 635 Problem Description Innocent Wu follows Dumb Zhang into a ancient tomb. Innocent Wu's at the en

HDOJ 5294 Tricks Device 最短路(记录路径)+最小割

最短路记录路径,同时求出最短的路径上最少要有多少条边, 然后用在最短路上的边重新构图后求最小割. Tricks Device Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1584    Accepted Submission(s): 388 Problem Description Innocent Wu follows Dumb Z