Barricade(HDU - 5889)

Problem Description

The empire is under attack again. The general of empire is planning to defend his castle. The land can be seen as N towns and M roads, and each road has the same length and connects two towns. The town numbered 1 is where general’s castle is located, and the town numbered N is where the enemies are staying. The general supposes that the enemies would choose a shortest path. He knows his army is not ready to fight and he needs more time. Consequently he decides to put some barricades on some roads to slow down his enemies. Now, he asks you to find a way to set these barricades to make sure the enemies would meet at least one of them. Moreover, the barricade on the i-th road requires wi units of wood. Because of lacking resources, you need to use as less wood as possible.

Input

The first line of input contains an integer t, then t test cases follow.
For each test case, in the first line there are two integers N(N≤1000) and M(M≤10000).
The i-the line of the next M lines describes the i-th edge with three integers u,v and w where 0≤w≤1000 denoting an edge between u and v of barricade cost w.

Output

For each test cases, output the minimum wood cost.

Sample Input

1
4 4
1 2 1
2 4 2
3 1 3
4 3 4

Sample Output

4

Source

2016 ACM/ICPC Asia Regional Qingdao Online

题意:

给出一个无向边组成的图,每条边有一个费用,现在要在每一条最短边上造一个路障,消耗的木材就是边的费用,求最小的费用和。

思路:

最大流/最小割。一开始的想法是最短路跑一遍得出最短的边,然后重新建图,去除最短路上没有使用过的边。
但EK算法的思想就是每次找最短增广路径,所以只需要记录每次bfs的最短距离,把所有最短距离相同的情况中的最大流量加起来,得到的就是答案,算是一个略带思维的模版题。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <vector>
#include <iostream>
#include <string>
#include <map>
#include <stack>
#include <cstring>
#include <queue>
#include <list>
#include <stdio.h>
#include <set>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <iomanip>
#include <cctype>
#include <sstream>
#include <iterator>
#include <functional>
#include <stdlib.h>
#include <time.h>
#include <bitset>
using namespace std;

#define pi acos(-1)
#define s_1(x) scanf("%d", &x)
#define s_2(x, y) scanf("%d%d", &x, &y)
#define s_3(x, y, z) scanf("%d%d%d", &x, &y, &z)
#define s_4(x, y, z, X) scanf("%d%d%d%d", &x, &y, &z, &X)
#define S_1(x) scan_d(x)
#define S_2(x, y) scan_d(x), scan_d(y)
#define S_3(x, y, z) scan_d(x), scan_d(y), scan_d(z)
#define sf_1(x) scan_lf(x)
#define sf_2(x, y) scan_lf(x), scanf_lf(y)
#define sf_3(x, y, z) scan_lf(x), scan_lf(y), scan_lf(z)
#define PI acos(-1)
#define endl '\n'
#define srand() srand(time(0));
#define me(x, y) memset(x, y, sizeof(x));
#define foreach(it, a) for(__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define close() ios::sync_with_stdio(0); cin.tie(0);
#define FOR(x, n, i) for (int i = x; i <= n; i++)
#define FOr(x, n, i) for (int i = x; i < n; i++)
#define fOR(n, x, i) for (int i = n; i >= x; i--)
#define fOr(n, x, i) for (int i = n; i > x; i--)
#define W while
#define sgn(x) ((x) < 0 ? -1 : (x) > 0)
#define bug printf("***********\n");
#define db double
#define ll long long
#define mp make_pair
#define pb push_back
typedef long long LL;
typedef pair <int, int> ii;
const int INF = 0x3f3f3f3f;
const LL LINF = 0x3f3f3f3f3f3f3f3fLL;
const int dx[] = {-1, 0, 1, 0, 1, -1, -1, 1};
const int dy[] = {0, 1, 0, -1, -1, 1, -1, 1};
const int maxn = 1e3 + 10;
const int maxx = 1e4 + 10;
const double EPS = 1e-8;
const double eps = 1e-10;
const int mod = 1e9 + 7;
const int MOD = 1e9 + 7;
template <class T> inline T min(T a, T b, T c) {return min(min(a, b), c);}
template <class T> inline T max(T a, T b, T c) {return max(max(a, b), c);}
template <class T> inline T min(T a, T b, T c, T d) {return min(min(a, b), min(c, d));}
template <class T> inline T max(T a, T b, T c, T d) {return max(max(a, b), max(c, d));}
template <class T> inline bool scan_d(T &ret) {
    char c;
    int sgn;
    if (c = getchar(), c == EOF) return 0;
    while (c != '-' && (c < '0' || c > '9')) c = getchar();
    sgn = (c == '-') ? -1 : 1;ret = (c == '-') ? 0 : (c - '0');
    while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
    ret *= sgn;
    return 1;
}
inline bool scan_lf(double &num) {
    char in;
    double Dec = 0.1;
    bool IsN = false, IsD = false;
    in = getchar();
    if (in == EOF) return false;
    while (in != '-' && in != '.' && (in < '0' || in > '9')) in=getchar();
    if (in == '-') {IsN = true; num = 0;}
    else if (in == '.') {IsD = true; num = 0;}
    else num = in - '0';
    if (!IsD) {
        while (in = getchar(), in >= '0' && in <= '9') {num *= 10; num += in - '0';}
    }
    if (in != '.') {
        if (IsN) num = -num;
        return true;
    }
    else{
        while (in = getchar(), in >= '0' && in <= '9') {
            num += Dec * (in - '0');
            Dec *= 0.1;
        }
    }
    if (IsN) num = num;
    return true;
}
void Out(LL a) {if(a < 0) {putchar('-'); a = -a;} if(a >= 10) Out(a / 10); putchar(a % 10 + '0');}
void print(LL a) {Out(a), puts("");}
/**********************************************WHITE_YASHA**********************************************/
//freopen( "in.txt" , "r" , stdin );
//freopen( "data.txt" , "w" , stdout );
//cerr << "run time is " << (db)(en - st) << endl;
int t, n, m;
int g[maxn][maxn], pre[maxn], min_len;
bool vis[maxn];
int bfs(int s, int e) {
    queue <ii> q;
    q.push(mp(s, 0));
    me(vis, false);
    me(pre, -1);
    vis[s] = true;
    W (!q.empty()) {
        ii u = q.front();
        q.pop();
        if (u.first == e) return u.second;
        FOR (1, n, v) {
            if (!vis[v] && g[u.first][v] > 0) {
                vis[v] = true;
                pre[v] = u.first;
                q.push(mp(v, u.second + 1));
            }
        }
    }
    return INF;
}
int EK(int s, int e) {
    min_len = INF;
    int ans = 0;
    W (true) {
        int tmp = bfs(s, e);
        if (tmp > min_len) break;
        min_len = tmp;
        int min_flow = INF;
        for (int i = e; i != s; i = pre[i])
            min_flow = min(min_flow, g[pre[i]][i]);
        for (int i = e; i != s; i = pre[i]) {
            g[pre[i]][i] -= min_flow;
            g[i][pre[i]] += min_flow;
        }
        ans += min_flow;
    }
    return ans;
}
int main() {
    s_1(t);
    W (t--) {
        s_2(n, m);
        me(g, 0);
        int u, v, w;
        FOr (0, m, i) {
            s_3(u, v, w);
            g[u][v] = g[v][u] = w;
        }
        printf("%d\n", EK(1, n));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值