您的位置:首页 > 理论基础 > 计算机网络

sgu185Two shortest 最短路+网络流+输出路径

2017-10-09 19:19 302 查看
其实就是先最短路,把所有最短路的边保存下来,之后求网络流

如果网络流>=2,我们就dfs输出所有的路径即可。

#include<iostream>  

#include<cstdio>  

#include<cstring>  

#include<algorithm>  

#include<queue>  

using namespace std;  

  

const int MAXN = 410;  

const int MAXM = 260100;  

const int INF = 0x3f3f3f3f;  

  

struct Edge  

{  

    int to, next, cap;  

};  

  

Edge edge[MAXM];  

int level[MAXN];  

int head[MAXN];  

int dist[MAXN];  

int map[MAXN][MAXN];  

int src, des, cnt, flag;  

  

void SPFA(int n)  

{  

    int inqueue[MAXN];  

    memset( dist, INF, sizeof dist );  

    memset( inqueue, 0, sizeof inqueue );  

    dist[1] = 0;      

    deque<int> dq;  

    dq.push_back( 1 );  

    inqueue[1] = 1;  

  

    while(!dq.empty())  

    {  

        int next = dq.front();  

        dq.pop_front();  

        inqueue[next] = 0;  

        for(int i = 1; i <= n; i++)  

        {  

            if(dist[i] > dist[next] + map[next][i])  

            {  

                dist[i] = dist[next] + map[next][i];  

                if(!inqueue[i])  

                {  

                    if(!dq.empty() && dist[i] > dist[dq.front()])  

                        dq.push_front( i );  

                    else  

                        dq.push_back( i );  

                }  

            }  

        }  

    }  

}  

  

void addedge( int from, int to, int cap )  

{  

    edge[cnt].to = to;  

    edge[cnt].cap = cap;  

    edge[cnt].next = head[from];  

    head[from] = cnt++;  

  

    swap( from, to );  

  

    edge[cnt].to = to;  

    edge[cnt].cap = 0;  

    edge[cnt].next = head[from];  

    head[from] = cnt++;  

}  

  

int bfs()  

{  

    memset( level, -1, sizeof level );  

    cnt = 0;  

    queue<int> q;  

    while (!q.empty())  

        q.pop();  

    level[src] = 0;  

    q.push( src );  

  

    while (!q.empty())  

    {  

        int u = q.front();  

        q.pop();  

  

        for (int i = head[u]; i != -1; i = edge[i].next)  

        {  

            int v = edge[i].to;  

            if (edge[i].cap > 0 && level[v] == -1)  

            {  

                level[v] = level[u] + 1;  

                q.push( v );  

            }  

        }  

    }  

    return level[des] != -1;  

}  

  

int dfs( int u, int f )  

{  

    if (u == des) return f;  

    int tem;  

  

    for (int i = head[u]; i != -1; i = edge[i].next)  

    {  

        int v = edge[i].to;  

        if (edge[i].cap > 0 && level[v] == level[u] + 1)  

        {  

            tem = dfs( v, min( f, edge[i].cap ) );  

            if (tem > 0)  

            {  

                edge[i].cap -= tem;  

                edge[i^1].cap += tem;  

                return tem;  

            }  

        }  

    }  

    level[u] = -1;  

    return 0;  

}  

  

int Dinic()  

{  

    int ans = 0, tem;  

    while (bfs())  

    {  

        while ((tem = dfs( src, INF )) > 0)  

        {  

            ans += tem;  

        }  

    }  

    return ans;  

}  

  

void print( int n, int u )  

{  

    if(u != n)  

    {  

        printf( "%d ", u );  

    }  

    else  

    {  

        printf( "%d\n", u );  

        flag = true;  

        return;  

    }  

  

    for(int i = head[u]; i != -1&&!flag; i = edge[i].next)  

    {  

        int v = edge[i].to;  

        if(edge[i].cap == 0 && i % 2 == 0)  

        {  

            edge[i].cap = -1;  

            print( n, v );  

        }  

    }  

}  

  

int main()  

{  

    int n,m;  

    while(cin >> n >> m)  

    {  

        src = 1, des = n;  

        memset( head, -1, sizeof head );  

        memset( map, INF, sizeof map );  

        for(int i = 1; i <= n; i++)  

            map[i][i] = 0;  

        cnt = 0;  

  

        int a, b, c;  

        for(int i = 1; i <= m; i++)  

        {  

            cin >> a >> b >> c;  

            map[a][b] = map[b][a] = c;  

        }  

        SPFA( n );  

  

        for(int i = 1; i <= n; i++)  

        {  

            for(int j = 1; j <= n; j++)  

            {  

                if(dist[i] + map[i][j] == dist[j])  

                {  

                    addedge( i, j, 1 );  

                }  

            }  

        }  

        int ans = Dinic();  

        if(ans < 2)  

            cout << "No solution" << endl;  

        else  

        {  

            print( n,src );  

            flag = false;  

            print( n, src );  

        }  

    }  

    return 0;  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: