【网络流】HDU 3599 War 最多不相交路径

来源:互联网 发布:dhcp 服务器端口 编辑:程序博客网 时间:2024/05/21 17:53

点击打开链接

求最多条 不相交的最短路

一次最短路 根据最短路建边

容量为1

#include <cstdio>#include <cstring>#include <cstdlib>#include <string>#include <iostream>#include <algorithm>#include <sstream>#include <cmath>using namespace std;#include <queue>#include <stack>#include <vector>#include <deque>#include <set>#include <map>#define clc(arr, val)    memset(arr, val, sizeof(arr))#define FOR(i,a,b)  for(int i=a;i<=b;i++)#define IN   freopen ("in.txt" , "r" , stdin);#define OUT  freopen ("out.txt" , "w" , stdout);typedef long long  LL;typedef unsigned long long  ULL;const int MAXN = 1550;const int MAXM = 600010;const int N = 30127;const int M = 200000;const int INF = 0x3f3f3f3f;const LL inf = 1e18;const LL mod = (LL)1<<32;const double eps= 1e-8;const double pi=acos(-1.0);#define lson l,m, rt<<1#define rson m+1,r,rt<<1|1int vis[MAXN],dis[MAXN],cost[MAXN][MAXN];int dijk(int n){    for(int i=0; i<n; i++)    {        dis[i]=INF;        vis[i]=false;    }    dis[0]=0;    for(int j=0; j<n; j++)    {        int k=-1;        int Min=INF;        for(int i=0; i<n; i++)            if(!vis[i]&&dis[i]<Min)            {                Min=dis[i];                k=i;            }        if(k==-1)break;        vis[k]=true;        for(int i=0;i<n;i++)        {            if(!vis[i]&&dis[k]+cost[i][k]<dis[i])            {                dis[i]=dis[k]+cost[i][k];            }        }    }}struct Edge{    int to,next,cap,flow;}edge[MAXM];//注意是MAXMint tol;int head[MAXN];int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];void init(){    tol = 0;    memset(head,-1,sizeof (head));}//加边,单向图三个参数,双向图四个参数void addedge (int u,int v,int w,int rw=0){    edge[tol].to = v;edge[tol].cap = w;edge[tol].next = head[u];    edge[tol].flow = 0;head[u] = tol++;    edge[tol].to = u;edge[tol].cap = rw;edge[tol]. next = head[v];    edge[tol].flow = 0;head[v]=tol++;}//输入参数:起点、终点、点的总数//点的编号没有影响,只要输入点的总数int sap(int start,int end, int N){    memset(gap,0,sizeof(gap));    memset(dep,0,sizeof(dep));    memcpy(cur,head,sizeof(head));    int u = start;    pre[u] = -1;    gap[0] = N;    int ans = 0;    int i;    while(dep[start] < N)    {        if(u == end)        {            int Min = INF;            for( i = pre[u];i != -1; i = pre[edge[i^1]. to])            {                if(Min > edge[i].cap - edge[i]. flow)                    Min = edge[i].cap - edge[i].flow;            }            for( i = pre[u];i != -1; i = pre[edge[i^1]. to])            {                edge[i].flow += Min;                edge[i^1].flow -= Min;            }            u = start;            ans += Min;            continue;        }        bool flag =  false;        int v;        for( i = cur[u]; i != -1;i = edge[i].next)        {            v = edge[i]. to;            if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u])            {                flag =  true;                cur[u] = pre[v] = i;                break;            }        }        if(flag)        {            u = v;            continue;        }        int Min = N;        for( i = head[u]; i !=  -1;i = edge[i]. next)        {            if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)            {                Min = dep[edge[i].to];                cur[u] = i;            }        }        gap[dep[u]]--;        if(!gap[dep[u]]) return ans;        dep[u] = Min+1;        gap[dep[u]]++;        if(u != start) u = edge[pre[u]^1].to;    }    return ans;}int main(){    int t,n,a,b,c;    cin>>t;    while(t--)    {        scanf("%d",&n);        for(int i=0;i<n;i++)        {            for(int j=0;j<n;j++)            cost[i][j]=INF;            cost[i][i]=0;        }        init();        while(scanf("%d%d%d",&a,&b,&c),a+b+c)        {            a--,b--;            cost[a][b]=cost[b][a]=min(cost[a][b],c);        }        dijk(n);        for(int i=0;i<n;i++)        {            for(int j=0;j<n;j++)            {                if(i==j) continue;                if(cost[i][j]+dis[i]==dis[j])                    addedge(i,j,1);            }        }        if(n==1||dis[n-1]==INF)            printf("0\n");        else{            int x=sap(0,n-1,n);            cout<<x<<endl;        }    }    return 0;}


0 0
原创粉丝点击