2014 UESTC Training for Graph Theory G

最短路问题可以dijkstra求两次最短路,有优先队列优化一下
第一次最短路就是从起点到各个终点的最短路
第二次最短路就是存一个逆图,权重值也逆,然后同样从起点跑最短路。

最后找出两次最短路和最大值输出就可以了

#include <map>
#include <set>
#include <list>
#include <cmath>
#include<cctype>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b)
{
	return a % b == 0 ? b : gcd(b, a % b);
}
#define MAXN 1005
#define INF 1e9
typedef pair<int ,int >pii;
int N,M,S;
int Max;
int first[MAXN];
int d[MAXN];
int d1[MAXN];
int w[MAXN][MAXN];
int w2[MAXN][MAXN];
vector <int> G[MAXN];
vector <int> G2[MAXN];
//int u[MAXN],v[MAXN],w[MAXN],next[MAXN];
priority_queue<pii,vector<pii>,greater<pii> >q;
void read_graph()
{
    int a,b,c;
    for (int i=0;i<N;i++) G[i].clear();
    for (int i=0;i<N;i++) G2[i].clear();
    for (int i=0;i<M;i++)
    {
        scanf("%d%d%d",&a,&b,&c);
        G[a-1].push_back(b-1);
        w[a-1][b-1]=c;
        G2[b-1].push_back(a-1);
        w2[b-1][a-1]=c;
    }
}
void dijkstra1()
{
    bool done[MAXN];
    for (int i=0;i<N;i++) if (i==S-1) d[i]=0;else d[i]=INF;
    memset(done,false,sizeof(done));
    while (!q.empty()) q.pop();
    q.push(make_pair(0,S-1));
    while (!q.empty())
    {
        pii u=q.top();q.pop();
        int x=u.second;
        //printf("cur start is %d\n",x);
        if (done[x]) continue;
        done[x]=true;
        for (int e=0;e<G[x].size();e++)
        {
            int v=G[x][e];
          //  printf("%d\n",v);
            if (d[v]>d[x]+w[x][v])
            {
             d[v]=d[x]+w[x][v];
             q.push(make_pair(d[v],v));
            }
        }
    }
    //for (int i=0;i<N;i++)
      //  printf("%d\n",d[i]);
}
void dijkstra2()
{
    bool done[MAXN];
    for (int i=0;i<N;i++) if (i==S-1) d1[i]=0;else d1[i]=INF;
    memset(done,false,sizeof(done));
    while (!q.empty()) q.pop();
    q.push(make_pair(0,S-1));
    while (!q.empty())
    {
        pii u=q.top();q.pop();
        int x=u.second;
        //printf("d1[%d] is %d\n",x,u.first);
        if (done[x]) continue;
        done[x]=true;
        for (int e=0;e<(int)G2[x].size();e++)
        {
            int v=G2[x][e];
           // printf("%d\n",v);
            if (d1[v]>d1[x]+w2[x][v])
            {
                //printf("d1[%d] is %d\n",v,d1[v]);
                //printf("%d\n",w2[x][v]);
             d1[v]=d1[x]+w2[x][v];
             //printf("cur d1[%d] is %d\n",v,d1[v]);
             q.push(make_pair(d1[v],v));
            }
        }
    }
    //for (int i=0;i<N;i++)
      //  printf("%d\n",d1[i]);
}
int main()
{
   freopen("sample.txt","r",stdin);
    while (scanf("%d%d%d",&N,&M,&S)!=EOF)
    {   memset(w2,0,sizeof(w2));
        memset(w,0,sizeof(w));
        memset(d,0,sizeof(d));
        memset(d1,0,sizeof(d1));
        read_graph();
        dijkstra1();
        dijkstra2();
        Max=-1;
        //printf("%d\n",Max);
        for (int i=0;i<N;i++)
         if (d1[i]+d[i]>Max) Max=d1[i]+d[i];
         printf("%d\n",Max);
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值