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

hdu 5294 Tricks Device

题目大意:吴邪在古墓中追张起灵,古墓中有很多条路,走每条路都需要一个时间,吴邪只有在最短的时间从古墓的入口到达出口才能追上张起灵。但是张起灵很厉害,他可以使用奇门遁甲使一条路无法通行。现在,问,张起灵最少堵住几条路就可以使吴邪追不上他,以及在吴邪可以追上张起灵的情况下,张起灵最多能堵多少条路。

解题思路:先求出古墓中的最短路(耗时最少的路),再求最短路的同时,记录走最短路要通过哪几条路和走最短路最少通过的路数。最多能堵住的路就是总的路数减去走最短路所要走过的最少的路数。然后根据最短路经过的路,来建网络流的图,求出的最大流,就是最少需要堵住的路。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <queue>
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const int N = 20005;

int n, m, s, t;
struct EdgeS {
    int from, to, dist;
};
vector<EdgeS> edgesS;
vector<int> GS[N];  

int visS[N], dS[N], rec[N];
void initS() {
    memset(visS, 0, sizeof(visS));
    for (int i = 0; i < N; i++) GS[i].clear();
    edgesS.clear();
}  

void addEdgeS(int from, int to, int dist) {
    edgesS.push_back((EdgeS){from, to, dist});
    edgesS.push_back((EdgeS){to, from, dist});
    int pos = edgesS.size();
    GS[from].push_back(pos - 2);
    GS[to].push_back(pos - 1);
}  

void SPFA() {
    memset(visS,0,sizeof(visS));
    for (int i = 0; i < N; i++) dS[i] = INF;
    for (int i = 0; i < N; i++) rec[i] = INF;
    dS[s] = 0;
    rec[s] = 0;
    visS[s] = 1;
    queue<int> Q;
    Q.push(s);
    while (!Q.empty()) {
        int u = Q.front();
        Q.pop();
        visS[u] = 0;
        for (int i = 0; i < GS[u].size(); i++) {
            int v = edgesS[GS[u][i]].to;
            if (dS[v] > dS[u] + edgesS[GS[u][i]].dist) {
                dS[v] = dS[u] + edgesS[GS[u][i]].dist;
                rec[v] = rec[u] + 1;
                if (!visS[v]) {
                    visS[v] = 1;
                    Q.push(v);
                }
            } else if (dS[v] == dS[u] + edgesS[GS[u][i]].dist) {
                if (rec[v] > rec[u] + 1) {
                    rec[v] = rec[u] + 1;
                    if (!visS[v]) {
                        visS[v] = 1;
                        Q.push(v);
                    }
                }
            }
        }
    }
}
struct Edge{
    int from, to, cap, flow;
};

vector<Edge> edges;
vector<int> G[N];

void init() {
    for (int i = 0; i < N; i++) G[i].clear();
    edges.clear();
}

void addEdge(int from, int to, int cap, int flow) {
    edges.push_back((Edge){from, to, cap, 0});
    edges.push_back((Edge){to, from, 0, 0});
    int m = edges.size();
    G[from].push_back(m - 2);
    G[to].push_back(m - 1);
} 

int vis[N], d[N];
int BFS() {
    memset(vis, 0, sizeof(vis));
    queue<int> Q;
    Q.push(s);
    d[s] = 0;
    vis[s] = 1;
    while (!Q.empty()) {
        int u = Q.front(); Q.pop();
        for (int i = 0; i < G[u].size(); i++) {
            Edge &e = edges[G[u][i]];
            if (!vis[e.to] && e.cap > e.flow) {
                vis[e.to] = 1;
                d[e.to] = d[u] + 1;
                Q.push(e.to);
            }
        }
    }
    return vis[t];
}

int cur[N];
int DFS(int u, int a) {
    if (u == t || a == 0) return a;
    int flow = 0, f;
    for (int &i = cur[u]; i < G[u].size(); i++) {
        Edge &e = edges[G[u][i]];
        if (d[u] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0) {
            e.flow += f;
            edges[G[u][i]^1].flow -= f;
            flow += f;
            a -= f;
            if (a == 0) break;
        }
    }
    return flow;
}

int MF() { //dinic算法求最大流
    int ans = 0;
    while (BFS()) {
        memset(cur, 0, sizeof(cur));
        ans += DFS(s, INF);
    }
    return ans;
}

int main() {
    while (scanf("%d %d", &n, &m) == 2) {
        int u, v, d;
        s = 0, t = n - 1;
        init();
        initS();
        for (int i = 0; i < m; i++) {
            scanf("%d %d %d", &u, &v, &d);
            if (u == v) continue;
            addEdgeS(u - 1, v - 1, d);
        }
        SPFA();
        for (int i = 0; i < edgesS.size(); i++) {
            if (dS[edgesS[i].to] == dS[edgesS[i].from] + edgesS[i].dist) {
                addEdge(edgesS[i].from, edgesS[i].to, 1, 0);
            }
        }
        printf("%d %d\n", MF(), m - rec[n - 1]);
    }
    return 0;
}

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

时间: 2024-10-14 00:11:04

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 (最大流+最短路)

题目链接: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

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

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

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

hdu5294 Tricks Device 最短路+最小割 多校联合第一场

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

HDU 5294 多校第一场1007题 最短路+最小割

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