hdu 5294 Tricks Device spfa+网络流

来源:互联网 发布:java list集合排序 编辑:程序博客网 时间:2024/05/21 07:06

题目要求两个答案,先求第二个答案,用spfa跑两次,第一次以1为起点,记录一下到终点最短距离通过了几条边。第二次以2为起点,跑一下。第一问题为最小移去多少条边,图不连通,题目中只需要移动最短路上的边,所以根据前两次spfa的结果,将最短路上的边找出来,流量记为1构成一张新图,转化为网络流问题,汇点的流量就是答案。

#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<queue>using namespace std;const int inf=0x7fffffff;const int N=2048;const int M=60000+5;int n,m,f[N],dis[N][2],cnt[N];struct{    int u,v,c;} edge[M];vector<int>g[M];struct Edge{    int from,to,cap,flow;};vector<Edge>edges;vector<int>G[N];int s,t;int vis[N];int d[N];int cur[N];int spfa(int st,int id){    queue<int>q;    int i,u,v,k;    memset(f,0,sizeof(f));    for(i=0; i<=n; i++)        cnt[i]=dis[i][id]=inf;    dis[st][id]=0;    cnt[st]=0;    q.push(st);    while(!q.empty())    {        u=q.front();        q.pop();        f[u]=0;        for(i=0; i<g[u].size(); i++)        {            k=g[u][i];            if(edge[k].u==u)                v=edge[k].v;            if(edge[k].v==u)                v=edge[k].u;            if(dis[u][id]+edge[k].c<=dis[v][id])            {                if(dis[u][id]+edge[k].c==dis[v][id])                    cnt[v]=min(cnt[u]+1,cnt[v]);                else                    cnt[v]=cnt[u]+1;                dis[v][id]=dis[u][id]+edge[k].c;                if(f[v]==0)                {                    f[v]=1;                    q.push(v);                }            }        }    }}void AddEdge(int from,int to,int cap){    Edge tp;    tp.from=from,tp.to=to,tp.cap=cap,tp.flow=0;    edges.push_back(tp);    tp.from=to,tp.to=from,tp.cap=0,tp.flow=0;    edges.push_back(tp);    int g_size=edges.size();    G[from].push_back(g_size-2);    G[to].push_back(g_size-1);}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==0) break;        }    }     if(!flow) d[x] = -1;    return flow;}int Maxflow(int st,int ed){    int flow=0;    while(BFS())    {        memset(cur,0,sizeof(cur));        flow+=DFS(st,inf);    }    return flow;}int main(){    int i,dist,ans,u,v,c;    while(~scanf("%d%d",&n,&m))    {        for(i=0; i<=n; i++)        {            g[i].clear();            G[i].clear();        }        edges.clear();        for(i=0; i<m; i++)        {            scanf("%d%d%d",&u,&v,&c);            edge[i].u=u;            edge[i].v=v;            edge[i].c=c;            g[u].push_back(i);            g[v].push_back(i);        }        spfa(1,0);        ans=cnt[n];        dist=dis[n][0];        spfa(n,1);        for(i=0; i<m; i++)        {            u=edge[i].u;            v=edge[i].v;            c=edge[i].c;            if(dis[u][0]+dis[v][1]+c==dist||dis[v][0]+dis[u][1]+c==dist)            {                AddEdge(u,v,1);                AddEdge(v,u,1);            }        }        s=1;t=n;        printf("%d %d\n",Maxflow(1,n),m-ans);    }    return 0;}
0 0
原创粉丝点击