HDU 5889 最短路加网络流

来源:互联网 发布:web软件测试工具 编辑:程序博客网 时间:2024/06/08 17:04

http://acm.hdu.edu.cn/showproblem.php?pid=5889


题意: 一个无向图,每条边距离为1,从N走到1,的最短路。。然后每个路有个价值,求一下最小割


思路:裸题。。手残BFS总是写错,后来换成SPFA枚举一下就好了。。注意!!!新图建单向边来跑最短路。


代码:

#include <iostream>#include <vector>#include <stdio.h>#include <queue>#include <cstring>#include <math.h>using namespace std;const int MAXN=1100;int maze[MAXN][MAXN];int Zdis[MAXN];int vis[MAXN];int gap[MAXN],dis[MAXN],pre[MAXN],cur[MAXN];const int INF=1e9+7;struct Edge{    int v;    int cost;    Edge(int _v=0,int _cost=0):v(_v),cost(_cost) {}};struct T{    int x,y,z;    T(int _x=0,int _y=0,int _z=0):x(_x),y(_y),z(_z) {}};int tmp[MAXN];vector<Edge>E[MAXN];vector<T> Z;void addedge(int u,int v,int w){    E[u].push_back(Edge(v,w));}void Add(int u,int v,int w){    Z.push_back(T(u,v,w));}int cnt[MAXN];//每个点的入队列次数int dist[MAXN];int n,m;bool SPFA(int start,int n){    memset(vis,false,sizeof(vis));    for(int i=1; i<=n; i++)dist[i]=INF;    vis[start]=true;    dist[start]=0;    queue<int>que;    while(!que.empty())que.pop();    que.push(start);    memset(cnt,0,sizeof(cnt));    cnt[start]=1;    while(!que.empty()){        int u=que.front();        que.pop();        vis[u]=false;        for(int i=0; i<E[u].size(); i++){            int v=E[u][i].v;            if(dist[v]>dist[u]+E[u][i].cost){                dist[v]=dist[u]+E[u][i].cost;                if(!vis[v]){                    vis[v]=true;                    que.push(v);                    if(++cnt[v]>n)return false;      //cnt[i]为入队列次数,用来判定是否存在负环回路                }            }        }    }    return true;}void init(){    for(int i=0;i<=n;i++) E[i].clear();    Z.clear();    memset(maze,0,sizeof(maze));}int sap(int start,int end,int nodenum){    memset(cur,0,sizeof(cur));    memset(dis,0,sizeof(dis));    memset(gap,0,sizeof(gap));    int u=pre[start]=start,maxflow=0,aug=-1;    gap[0]=nodenum;    while(dis[start]<nodenum){        loop:        for(int v=cur[u]; v<nodenum; v++)            if(maze[u][v] && dis[u]==dis[v]+1){                if(aug==-1 || aug>maze[u][v])aug=maze[u][v];                pre[v]=u;                u=cur[u]=v;                if(v==end){                    maxflow+=aug;                    for(u=pre[u]; v!=start; v=u,u=pre[u]){                        maze[u][v]-=aug;                        maze[v][u]+=aug;                    }                    aug=-1;                }                goto loop;            }        int mindis=nodenum-1;        for(int v=0; v<nodenum; v++)            if(maze[u][v]&&mindis>dis[v]){                cur[u]=v;                mindis=dis[v];            }        if((--gap[dis[u]])==0)break;        gap[dis[u]=mindis+1]++;        u=pre[u];    }    return maxflow;}int main(){    int t;    cin>>t;    while(t--){        scanf("%d%d",&n,&m);        int a,b,c;        init();        for(int i=0;i<m;i++){            scanf("%d%d%d",&a,&b,&c);            addedge(a,b,1);            addedge(b,a,1);            Add(a,b,c);            Add(b,a,c);        }        if(!SPFA(1,n)){            printf("0\n");            continue;        }        for(int i=0;i<=n;i++) tmp[i]=dist[i];        SPFA(n,n);        for (int i=0;i<Z.size();i++){            if (dist[Z[i].x]+tmp[Z[i].y]+1==dist[1]) {                maze[Z[i].x-1][Z[i].y-1]+=Z[i].z;            }        }        int ans=sap(n-1,0,n);        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击