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

来源:互联网 发布:编程好看的字体 编辑:程序博客网 时间:2024/06/10 14:43

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

题目大意:
n点m边无向图,1为己方 n为敌方
每条边有建阻碍的花费 距离都是1

已知敌方会选择最短路来己方。要选择一些路设障碍,让敌方至少碰到一个障碍。

先跑一个最短路。

对于每条边uv,如果dis[v]==dis[u]+1||dis[u]==dis[v]+1

这条路就可能在最短路中。

然后跑个最小割(其实就是最大流)

为什么酱紫保证正确呢?赛后我也有怀疑是水数据。。

后来金巨一句点醒梦中人。。

如果不是最短路中的边,肯定无法跑到终点,至少会有一处断开。所以大胆跑最小割就行了

代码如下:

#include <iostream>#include <cmath>#include <vector>#include <cstdlib>#include <cstdio>#include <climits>#include <ctime>#include <cstring>#include <queue>#include <stack>#include <list>#include <algorithm>#include <map>#include <set>#define LL long long#define Pr pair<int,int>#define fread(ch) freopen(ch,"r",stdin)#define fwrite(ch) freopen(ch,"w",stdout)using namespace std;const int INF = 0x3f3f3f3f;const int mod = 1e9+7;const double eps = 1e-8;const int maxn = 1111,maxm = 11111;struct Edge{    int v,w,next;} eg[maxm*5],teg[maxm*5];int ds[maxn];bool vis[maxn];int head[maxn],thead[maxn];int n,tp,ttp,st,en;void Add(int u,int v,int w){    eg[tp].v = v;    eg[tp].w = w;    eg[tp].next = head[u];    head[u] = tp++;    eg[tp].v = u;    eg[tp].w = 0;    eg[tp].next = head[v];    head[v] = tp++;}void add(int u,int v,int w){    teg[ttp].v = v;    teg[ttp].w = w;    teg[ttp].next = thead[u];    thead[u] = ttp++;}int dis[maxn];int gap[maxn];int pre[maxn];int cur[maxn];int isap(){    memset(dis,0,sizeof(dis));    memset(gap,0,sizeof(gap));    memset(pre,-1,sizeof(pre));    memset(cur,-1,sizeof(cur));    gap[0] = n;    int u,v,flow,ans;    flow = INF;    u = pre[0] = 0;    ans = 0;    while(dis[1] < en)    {        for(int &i = cur[u]; i != -1; i = eg[i].next)        {            if(eg[i].w && dis[eg[i].v]+1 == dis[u]) break;        }        if(cur[u] != -1)        {            v = eg[cur[u]].v;            flow = min(flow,eg[cur[u]].w);            pre[v] = u;            u = v;            if(u == en)            {                for(; u != 0; u = pre[u])                {                    eg[cur[pre[u]]].w -= flow;                    eg[cur[pre[u]]^1].w += flow;                }                ans += flow;                flow = INF;            }        }        else        {            int mn = n;            for(int i = head[u]; i != -1; i = eg[i].next)            {                if(eg[i].w && dis[eg[i].v] < mn)                {                    mn = dis[eg[i].v];                    cur[u] = i;                }            }            if(!(--gap[dis[u]])) break;            dis[u] = mn+1;            gap[dis[u]]++;            u = pre[u];        }    }    return ans;}void bfs(){    queue <int> q;    memset(vis,0,sizeof(vis));    memset(ds,INF,sizeof(ds));    ds[0] = 0;    q.push(0);    int u,v;    while(!q.empty())    {        u = q.front();        q.pop();        vis[u] = 0;        for(int i = thead[u]; i != -1; i = teg[i].next)        {            v = teg[i].v;            if(ds[v] > ds[u]+1)            {                ds[v] = ds[u]+1;                if(!vis[v])                {                    q.push(v);                    vis[v] = 1;                }            }        }    }}int main(){    //fread();    //fwrite();    int t;    int m;    int u,v,w;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        memset(head,-1,sizeof(head));        memset(thead,-1,sizeof(thead));        tp = ttp = 0;        st = 0,en = n-1;        for(int i = 0; i < m; ++i)        {            scanf("%d%d%d",&u,&v,&w);            u--,v--;            add(u,v,w);            add(v,u,w);        }        bfs();        for(int i = 0; i < n; ++i)        {            for(int j = thead[i]; j != -1; j = teg[j].next)            {                u = i;                v = teg[j].v;                if(ds[v] == ds[u]+1)                {                    //printf("%d %d\n",u,v);                    Add(u,v,teg[j].w);                }            }        }        printf("%d\n",isap());    }    return 0;}
0 0
原创粉丝点击