HDU 5889 Barricade(最小割+最短路)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37943488/article/details/82120307

Barricade

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


 

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

题目大意:给一个N个点M条边的图,坏人要从1点走到N点,但是坏人每次都只走最短路,你可以当一些路障在一些边上,但是需要花费,问最少的花费使得坏人走不到

还挺明显的最小割,先求出最短路,然后拿那些给出的边且在最短路上的边建图,跑一遍网络流即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=1010;
const int maxm=10010;
const int inf=0x3f3f3f3f;
struct LDj
{
    int from;
    int to;
    int len;
    int capa;
    int next;
}path[maxm];
struct Node
{
    int to;
    int capa;
    int next;
}edge[maxm];
int source,sink;
int cntpath;
int headpath[maxn];
int cnt;
int head[maxn];
int dis[maxn];
bool vis[maxn];
int dep[maxn];
void init()
{
    memset(headpath,-1,sizeof(headpath));
    memset(head,-1,sizeof(head));
    cnt=0;
    cntpath=0;
    return;
}
void add(int u,int v,int capa)
{
    edge[cnt].to=v;
    edge[cnt].capa=capa;
    edge[cnt].next=head[u];
    head[u]=cnt++;
    edge[cnt].to=u;
    edge[cnt].capa=0;
    edge[cnt].next=head[v];
    head[v]=cnt++;
    return;
}
void addpath(int u,int v,int capa,int len)
{
    path[cntpath].from=u;
    path[cntpath].capa=capa;
    path[cntpath].to=v;
    path[cntpath].next=headpath[u];
    path[cntpath].len=len;
    headpath[u]=cntpath++;
    path[cntpath].from=v;
    path[cntpath].capa=capa;
    path[cntpath].to=u;
    path[cntpath].next=headpath[v];
    path[cntpath].len=len;
    headpath[v]=cntpath++;
    return;
}
void spfa()
{
    queue<int> que;
    que.push(source);
    memset(dis,inf,sizeof(dis));
    memset(vis,false,sizeof(vis));
    dis[source]=0;
    vis[source]=true;
    while(!que.empty())
    {
        int node=que.front();
        que.pop();
        vis[node]=false;
        for(int i=headpath[node];~i;i=path[i].next)
        {
            int v=path[i].to;
            if(dis[v]>dis[node]+1)
            {
                dis[v]=dis[node]+1;
                if(!vis[v])
                {
                    vis[v]=true;
                    que.push(v);
                }
            }
        }
    }
    return;
}
bool bfs()
{
    queue<int> que;
    que.push(source);
    memset(dep,-1,sizeof(dep));
    dep[source]=0;
    while(!que.empty())
    {
        int node=que.front();
        que.pop();
        for(int i=head[node];~i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(edge[i].capa>0&&dep[v]==-1)
            {
                dep[v]=dep[node]+1;
                if(v==sink) return true;
                que.push(v);
            }
        }
    }
    return dep[sink]!=-1;
}
int dfs(int node,int minn)
{
    if(node==sink||minn==0)
    {
        return minn;
    }
    int r=0;
    for(int i=head[node];~i;i=edge[i].next)
    {
        int v=edge[i].to;
        if(dep[v]==dep[node]+1&&edge[i].capa>0)
        {
            int tmp=dfs(v,min(edge[i].capa,minn));
            if(tmp>0)
            {
                edge[i].capa-=tmp;
                edge[i^1].capa+=tmp;
                r+=tmp;
                minn-=tmp;
                if(!minn) break;
            }
        }
    }
    if(!r) dep[node]=-1;
    return r;
}
int dinic()
{
    int maxflow=0;
    while(bfs())
    {
        maxflow+=dfs(source,inf);
    }
    return maxflow;
}
int main()
{
    int test;
    scanf("%d",&test);
    while(test--)
    {
        init();
        int n,m;
        scanf("%d%d",&n,&m);
        source=1;
        sink=n;
        for(int i=0;i<m;i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            addpath(u,v,w,1);
        }
        spfa();
        for(int i=0;i<cntpath;i+=2)
        {
            int u=path[i].from;
            int v=path[i].to;
            if(dis[u]==dis[v]+1)
            {
                add(v,u,path[i].capa);
            }
            else if(dis[v]==dis[u]+1)
            {
                add(u,v,path[i].capa);
            }
        }
        printf("%d\n",dinic());
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37943488/article/details/82120307
今日推荐