UVA 10806 Dijkstra, Dijkstra.

来源:互联网 发布:网络本科学位 编辑:程序博客网 时间:2024/06/06 00:28
Dijkstra, Dijkstra.

Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu


Description

Download as PDF

大致题意:求从起点走到终点,再从终点走到起点,求最短路径。注:不能同时走相同的一条边

分析:一开始我是先求一条最短路径,然后将所走过的边进行标记(相当于删除),再求一次最短路径。结果wa了,后来发现这样求得到的不一定是最优解。查了资料才发现这属于最小费用最大流问题,然后写了以下代码:

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<queue>using namespace std;const int INF = 0x3f3f3f3f;int n,m;int a[110][110];//邻接矩阵int vis[110];//标记是否在队列中,“1”是,“0”否int dist[110];//dist[i]表示从起点到vi的最短路径的长度int path[110];//path[i]表示从起点到vi的最短路径上顶点vi的前一个顶点序号void Bellman_Ford(){    memset(vis,0,sizeof(vis));    memset(path,-1,sizeof(path));    memset(dist,INF,sizeof(dist));    queue<int>que;    que.push(1);    dist[1] = 0;    vis[1] = 1;    while(que.size())    {        int x = que.front();        que.pop();        vis[x] = 0; //清除“在队列中”标志        for(int i = 1;i <= n;i++)        {            if(dist[i] > dist[x] + a[x][i])            {                dist[i] = dist[x] + a[x][i];                path[i] = x;                if(!vis[i]) //如果已经在队列中,就不要重复加了                {                    vis[i] = 1;                    que.push(i);                }            }        }    }}int main(){   while(~scanf("%d",&n))   {       if(n == 0)            break;       scanf("%d",&m);       memset(a,INF,sizeof(a));//初始化邻接矩阵       for(int i = 0;i < n;i++)            a[i][i] = 0;       int u,v,w;       for(int i = 0;i < m;i++)       {           scanf("%d %d %d",&u,&v,&w);           a[u][v] = w;           a[v][u] = w;       }       Bellman_Ford();//求最短路径       int ans = dist[n];       int s = 1,t = n;       /*将第一次求得的最短路径所经过的边进行修改       例如:经过了边(u,v),则先将a[v][u] = -[u][v],然后将a[u][v] 修改为INF,然后第二次寻找最短路*/       while(s != t)       {           a[t][path[t]] = -a[path[t]][t];           a[path[t]][t] = INF;           t = path[t];       }       Bellman_Ford();       int res = dist[n];       if(ans == INF || res == INF)       {           printf("Back to jail\n");            continue;       }       ans += res;       printf("%d\n",ans);   }   return 0;}


0 0