poj3268 Silver Cow Party(农场派对)
题目描述
原题来自:USACO 2007 Feb. Silver
N(1≤N≤1000)N (1 \le N \le 1000)N(1≤N≤1000) 头牛要去参加一场在编号为 x(1≤x≤N)x(1 \le x \le N)x(1≤x≤N) 的牛的农场举行的派对。有 M(1≤M≤100000)M(1\le M \le 100000)M(1≤M≤100000) 条有向道路,每条路长 Ti(1≤Ti≤100)T_i(1 \le T_i \le 100)Ti(1≤Ti≤100);每头牛都必须参加完派对后回到家,每头牛都会选择最短路径。求这 NNN 头牛的最短路径(一个来回)中最长的一条的长度。 特别提醒:可能有权值不同的重边。
输入格式
第 111 行:333 个空格分开的整数 N,M,XN,M,XN,M,X;
第 2…M+12 \ldots M+12…M+1 行:333 个空格分开的整数 Ai,Bi,TiA_i, B_i, T_iAi,Bi,Ti,表示有一条从 AiA_iAi 到 BiB_iBi 的路,长度为 TiT_iTi。
输出格式
一行一个数,表示最长最短路的长度。
样例
样例输入
4 8 2
1 2 4
1 3 2
1 4 7
2 1 1
2 3 5
3 1 2
3 4 4
4 2 3
样例输出
10
翻译题目,我们需要知道关于一个点,它到所有点的最短路以及所有点到它的最短路。
前者是最短路模板,后者是将所有边反着连,跑一边模板。
至于用Dijkstra还是SPFA,一看,没有负权边,向上看,我叫什么?
好了,用Dijkstra。
#include <iostream> #include <cstdio> #include <algorithm> #include <cstdlib> #include <cstring> #include <queue> #define in(a) a=read() #define REP(i,k,n) for(int i=k;i<=n;i++) #define MAXN 100010 using namespace std; inline int read(){ int x=0,f=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return x*f; } int n,m,s,ans=-2147483647; int total1,head1[MAXN],to1[MAXN],nxt1[MAXN],val1[MAXN]; int total2,head2[MAXN],to2[MAXN],nxt2[MAXN],val2[MAXN]; int dis1[MAXN],vis1[MAXN]; int dis2[MAXN],vis2[MAXN]; struct node{ int a,b; }; priority_queue<node> Q; bool operator < (node x,node y){ return x.b > y.b; } inline void adl1(int a,int b,int c){ total1++; to1[total1]=b; val1[total1]=c; nxt1[total1]=head1[a]; head1[a]=total1; return ; } inline void adl2(int a,int b,int c){ total2++; to2[total2]=b; val2[total2]=c; nxt2[total2]=head2[a]; head2[a]=total2; return ; } void dijkstra1(){ dis1[s]=0; Q.push(node{s,0}); while(!Q.empty()){ int u=Q.top().a; Q.pop(); if(vis1[u]) continue; vis1[u]=1; for(int e=head1[u];e;e=nxt1[e]) if(dis1[to1[e]]>dis1[u]+val1[e]){ dis1[to1[e]]=dis1[u]+val1[e]; Q.push(node{to1[e],dis1[to1[e]]}); } } return ; } void dijkstra2(){ dis2[s]=0; Q.push(node{s,0}); while(!Q.empty()){ int u=Q.top().a; Q.pop(); if(vis2[u]) continue; vis2[u]=1; for(int e=head2[u];e;e=nxt2[e]) if(dis2[to2[e]]>dis2[u]+val2[e]){ dis2[to2[e]]=dis2[u]+val2[e]; Q.push(node{to2[e],dis2[to2[e]]}); } } return ; } int main(){ in(n),in(m),in(s); int a,b,c; REP(i,1,m) in(a),in(b),in(c),adl1(a,b,c),adl2(b,a,c); REP(i,1,n) dis1[i]=dis2[i]=2147483647; dijkstra1(); dijkstra2(); REP(i,1,n) ans=max(ans,dis1[i]+dis2[i]); cout<<ans; }