HDU 5889 Barricade (单源最短路 + 最小割(最大流))

来源:互联网 发布:知乎 国企校园招聘 编辑:程序博客网 时间:2024/05/18 18:16

大体题意:

给你一个无向图,告诉你敌人在点n,我方在点1,敌人要从n 走到1,他们一定会选择最短路,你可以向一些路放一些木头来阻碍敌人,放木头的代价为路的权值,求最小权值使得敌人一定会经过一个木头?

思路:

比赛没有出,借鉴了学长们的博客!

因为敌人一定会走最短路,那么我们可以先构造出所有的最短路!

因为要找一些权值最小的和,想一想可以知道 ,这是找最小割!

因为一定要走到1点吗,最小割不就是划分一部分S区域,一部分T区域,求他们的最小有向边和嘛!

因此,我们判断每一条边,如果是最短路里的边,就加入到网路中!

最后求一遍最大流!

判断是否是最短路也很简单:

也求一遍N到任意一点的最短路 Dijkstra算法!

然后判断这个边的两个端点  最短路之差为1的话,那就是最短路了!

详细见代码:

#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>using namespace std;const int maxn = 1000 + 10;const int inf = 0x3f3f3f3f;struct Edge{    int from, to, cap, flow;    Edge(int from = 0,int to = 0, int cap = 0,int flow = 0):from(from),to(to), cap(cap), flow(flow){}};struct Dinic{    int n, m, s, t;    vector<Edge> edges;    vector<int> G[maxn];    bool vis[maxn];    int d[maxn];    int cur[maxn];    void AddEdge(int from,int to,int cap){        edges.push_back(Edge(from,to,cap,0));        edges.push_back(Edge(to,from,0,0));        m = edges.size();        G[from].push_back(m-2);        G[to].push_back(m-1);    }    void init(int n){        this->n = n;        for (int i = 0; i <= n; ++i)G[i].clear();        edges.clear();    }    bool BFS(){        memset(vis,0,sizeof vis);        queue<int> Q;        Q.push(s);        d[s] = 0;        vis[s] = 1;        while(!Q.empty()){            int x = Q.front(); Q.pop();            for (int i = 0; i < G[x].size(); ++i){                Edge& e = edges[G[x][i]];                if (!vis[e.to] && e.cap > e.flow) {                    vis[e.to] = 1;                    d[e.to] = d[x] + 1;                    Q.push(e.to);                }            }        }        return vis[t];    }    int DFS(int x,int a){        if (x == t || a == 0) return a;        int flow = 0, f;        for (int& i = cur[x]; i < G[x].size(); ++i){            Edge& e = edges[G[x][i]];            if (d[x] + 1 == d[e.to] && (f = DFS(e.to,min(a, e.cap-e.flow))) > 0){                e.flow += f;                edges[G[x][i]^1].flow -= f;                flow += f;                a -= f;                if (!a)break;            }        }        return flow;    }    int MaxFlow(int s,int t){        this->s = s;        this->t = t;        int flow=0;        while(BFS()){            memset(cur,0,sizeof cur);            flow += DFS(s,inf);        }        return flow;    }}mmf;struct Edge2{    int from, to, dist,cost;    Edge2(int from = 0,int to = 0, int dist = 0,int cost = 0):from(from),to(to),dist(dist),cost(cost){}};struct HeapNode{    int d,u;    HeapNode(int d = 0,int u = 0):d(d),u(u){}    bool operator < (const HeapNode& rhs) const {        return d > rhs.d;    }};struct Dijkstra{    int n, m;    vector<Edge2> edges;    vector<int> G[maxn];    bool done[maxn];    int d[maxn];    int p[maxn];    void init(int n){        this->n = n;        m = 0;        for (int i = 0; i <= n; ++i) G[i].clear();        edges.clear();    }    void AddEdge(int from,int to,int dist,int cost){        edges.push_back(Edge2(from,to,dist,cost));        ++m;        G[from].push_back(m-1);    }    void dijkstra(int s){        priority_queue<HeapNode>Q;        for (int i = 0; i <= n; ++i)d[i] = inf;        d[s] = 0;        memset(done,0,sizeof done);        Q.push(HeapNode(0,s));        while(!Q.empty()){            HeapNode x = Q.top(); Q.pop();            int u = x.u;            if (done[u]) continue;            done[u] = 1;            for (int i = 0; i < G[u].size(); ++i){                Edge2& e = edges[G[u][i]];                if (d[e.to] > d[u] + e.dist){                    d[e.to] = d[u] + e.dist;                    p[e.to] = G[u][i];                    Q.push(HeapNode(d[e.to],e.to));                }            }        }    }}dij;int main(){    int T;    scanf("%d",&T);    while(T--){        int n,m;        scanf("%d %d",&n,&m);        dij.init(n);        mmf.init(n);        for (int i = 0; i < m; ++i){            int u,v,w;            scanf("%d %d %d",&u,&v,&w);            dij.AddEdge(u,v,1,w);            dij.AddEdge(v,u,1,w);        }        dij.dijkstra(n);        int len = dij.edges.size();        for (int i = 0; i < len; i += 2){            int u = dij.edges[i].from;            int v = dij.edges[i].to;            int w = dij.edges[i].cost;            if (dij.d[v] - 1 == dij.d[u]){                mmf.AddEdge(u,v,w);//                printf("%d %d %d\n",u,v,w);                continue;            }            u = dij.edges[i+1].from;            v = dij.edges[i+1].to;            w = dij.edges[i+1].cost;            if (dij.d[v] - 1 == dij.d[u]){                mmf.AddEdge(u,v,w);//                printf("%d %d %d\n",u,v,w);                continue;            }        }        int ans = mmf.MaxFlow(n,1);        printf("%d\n",ans);    }    return 0;}

Barricade

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 732    Accepted Submission(s): 216



Problem Description
The empire is under attack again. The general of empire is planning to defend his castle. The land can be seen asN towns and M roads, and each road has the same length and connects two towns. The town numbered1 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 thei-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(N1000) and M(M10000).
The i-the line of the next M lines describes the i-th edge with three integers u,v and w where 0w1000 denoting an edge between u and v of barricade cost w.
 

Output
For each test cases, output the minimum wood cost.
 

Sample Input
14 41 2 12 4 23 1 34 3 4
 

Sample Output
4
 

Source
2016 ACM/ICPC Asia Regional Qingdao Online
 

Recommend
wange2014   |   We have carefully selected several similar problems for you:  5901 5900 5899 5898 5897 
 

0 0
原创粉丝点击