HDU 3870 Catch the Theves(对偶图的最小割转最短路)

来源:互联网 发布:竞彩软件 编辑:程序博客网 时间:2024/06/06 18:02

题目地址
题意:小偷从左上角出发,要到达右下角,问警察至少拦截多长的路一定可以抓到小偷。(给的数num[i][j]的意思是(i,j)这点到(i+1,j)和(i,j+1)的距离)
思路:看到这题就想到用最小割,当左上角和右下角不连通的时候就可以抓到小偷了,但是用Dinic去写的话,就会发现复杂度太高了,然后上网百度发现了是对偶图的最小割转最短路的转发,可以看这个去理解,然后就是模板题了(建图方法看下面)。
对应我代码的建图方法的图片:对应我代码的建图方法的图片:

PS:还有一个蛮有趣的博客讲这个的推荐一下。

#include <iostream>#include <cstring>#include <string>#include <queue>#include <vector>#include <map>#include <set>#include <stack>#include <cmath>#include <cstdio>#include <algorithm>#include <iomanip>#define N 410#define M 170050#define LL __int64#define inf 0x3f3f3f3f#define lson l,mid,ans<<1#define rson mid+1,r,ans<<1|1#define getMid (l+r)>>1#define movel ans<<1#define mover ans<<1|1using namespace std;const LL mod = 1000000007;int mapp[N][N];int head[M], cnt;bool vis[M];int len[M];struct node {    int to, len;    int next;}edge[M*5];struct SPFA {    void init() {        memset(head, -1, sizeof(head));        cnt = 0;    }    void addyes(int a, int b, int c) {        edge[cnt].to = b;        edge[cnt].len = c;        edge[cnt].next = head[a];        head[a] = cnt++;    }    void addno(int a, int b, int c) {        edge[cnt].to = b;        edge[cnt].len = c;        edge[cnt].next = head[a];        head[a] = cnt++;        edge[cnt].to = a;        edge[cnt].len = c;        edge[cnt].next = head[b];        head[b] = cnt++;    }    int spfa(int s, int t) {        memset(vis, false, sizeof(vis));        memset(len, inf, sizeof(len));        len[s] = 0;        vis[s] = true;        queue<int> q;        q.push(s);        while (!q.empty()) {            int u = q.front();            q.pop();            for (int i = head[u]; ~i; i = edge[i].next) {                int v = edge[i].to;                int dis = edge[i].len;                if (len[v] > len[u] + dis) {                    len[v] = len[u] + dis;                    if (!vis[v]) {                        q.push(v);                        vis[v] = true;                    }                }            }            vis[u] = false;        }        return len[t];    }}Spfa;int main() {    //cin.sync_with_stdio(false);    int T, n;    scanf("%d", &T);    //cin >> T;    while (T--) {        Spfa.init();        scanf("%d", &n);        for (int i = 1; i <= n; i++) {            for (int j = 1; j <= n; j++) {                scanf("%d", &mapp[i][j]);            }        }        int s = 0;        int t = (n - 1)*(n - 1) + 1;        for (int i = 1; i < n; i++) {            Spfa.addno(s, (i - 1)*(n - 1) + 1, mapp[i][1]);//s面            Spfa.addno(s, (n - 2)*(n - 1) + i, mapp[n][i]);            Spfa.addno(t, (i - 1)*(n - 1) + n - 1, mapp[i][n]);//t面            Spfa.addno(t, i, mapp[1][i]);        }        for (int i = 1; i < n; i++) {            for (int j = 1; j < n; j++) {                if (i > 1) Spfa.addno((i - 2)*(n - 1) + j, (i - 1)*(n - 1) + j, mapp[i][j]);                if (j > 1) Spfa.addno((i - 1)*(n - 1) + j - 1, (i - 1)*(n - 1) + j, mapp[i][j]);            }        }        printf("%d\n", Spfa.spfa(s, t));    }    return 0;}
阅读全文
0 0
原创粉丝点击