POJ - 3268 Silver Cow Party (dijkstra)

题意:草场上有n个农场,农场之间有一些路径,每个农场里住着一头牛,现在x农场的牛要过生日开party,其他农场的牛要到该农场去参加party,

现在让你选择一头来回耗时最多的一头牛出来,输出时间。给你一个n个结点、m条边的有向图,现在要你求从n-1个结点到达指定的一个结点的来回最长路

思路:如果返程的部分是从n求向1的就要求n次所以,我们把边全部反向一边再来求;
但是使用链式向前星的时候遇到一个问题,就是如何逆置边。
就想到了使用标记变量,一个正向(1)一个逆向(0) ; 当我们第一次正向过去遍历时,遇到flag =0 的边就跳过, 反之 第二遍遇到flag = 1 的边就跳过

 

一开始TLE了半天一直找不到问题,然后随手乱改就把 Q.size()这个判断改成  !Q.empty() 就过了...

完整代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;

const int inf = 0x3f3f3f3f;
const int max_size = 1e3+10;
const int max_edge = 1e5+5;
typedef pair<int,int> pi;
struct Edge{
    int u;
    int v,w,next;
    int flag ;
}edge[max_edge<<1];
int head[max_size];
int dist[max_size];
int back[max_size];
int top;
int n,m;

void init(){
    memset(dist,inf,sizeof(dist));
    memset(head,-1,sizeof(head));
    memset(back,inf,sizeof(back));
}
void add(int u,int v,int w){
    //即把两种都链接上,然后对应关系进行跳过 
    edge[top].u = u;
    edge[top].v = v;
    edge[top].w = w;
    edge[top].flag = 1;
    edge[top].next = head[u];
    head[u] = top++;
    
    edge[top].v = u;
    edge[top].u = v;
    edge[top].w = w;
    edge[top].flag= 0;
    edge[top].next= head[v];
    head[v]=top++;
}

void dijkstra(int s,bool flag){
    priority_queue<pi>Q;
    Q.push(make_pair(0,s));
    while(!Q.empty()){
        s = Q.top().second;
        Q.pop();
        for(int i = head[s]; ~i;i = edge[i].next){
            if(flag){//跳过 
                if(!edge[i].flag)  continue;
            }
            else{
                if(edge[i].flag) continue;
            }
            
            if(flag){
                if(dist[edge[i].v]>dist[s]+edge[i].w){
                    dist[edge[i].v] = dist[s]+edge[i].w ;
                    Q.push(make_pair(-dist[edge[i].v],edge[i].v));
                }
            }else{
                if(back[edge[i].v]>back[s]+edge[i].w){
                    back[edge[i].v] = back[s]+edge[i].w ;
                    Q.push(make_pair(-back[edge[i].v],edge[i].v));
                }
            }
            
        }
    }
}
int main(){
    int s;
    while(cin>>n>>m>>s)
    {
        init(); 
        for(int i=0;i<m;i++){
            int u,v,w;
            cin>>u>>v>>w;
            add(u,v,w);
        }
        back[s] = dist[s] = 0;
        dijkstra(s,1);
        dijkstra(s,0);
        int ans  = -1;
        
        for(int i= 1;i<=n;i++){
            if(i == s) continue;
            ans = max(ans,back[i]+dist[i]);
        }
        cout<<ans<<endl;
    }
}

 

posted @ 2019-08-01 19:09  Tianwell  阅读(133)  评论(0编辑  收藏  举报