USACO 2007 Feb. Silver 农场派对

N头牛要去参加一场在编号为x(1≤x≤n)的牛的农场举行的派对(1≤N≤1000),有M(1≤m≤100000)条有向道路,每条路长ti(1≤ti≤100);每头牛都必须参加完派对后回到家,每头牛都会选择最短路径,求这n个牛的最短路径(一个来回)中最长的一条的长度。


是最短路的模板题,正反连边,跑两遍最短路,然后选出和最大的(注意反向连边要赋初值)

我用的是DIJ因为图较为稠密,当然SPFA也是可以过的

下面给出代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;
inline int min(int a,int b){return a<b?a:b;}
inline int max(int a,int b){return a>b?a:b;}
inline int rd(){
    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;
}
inline void write(int x){
     if(x<0) putchar('-'),x=-x;
     if(x>9) write(x/10);
     putchar(x%10+'0');
     return ;
}
int n,m,s;
int head[100006];
int nxt[200006],to[200006],v[200006];
int total=0;
void add(int x,int y,int z){
    total++;
    to[total]=y;
    v[total]=z;
    nxt[total]=head[x];
    head[x]=total;
    return ;
}
struct node{
    int u,v;
    bool operator<(const node x) const{
        return u>x.u;
    }
};
priority_queue <node> Q;
int dis[100006];
int book[100006];
void dij(int x){
    dis[x]=0;
    node h;
    h.v=x;
    h.u=0;
    Q.push(h);
    while(!Q.empty()){
        h=Q.top();
        Q.pop();
        if(book[h.v]) continue;
        book[h.v]=1;
        for(int e=head[h.v];e;e=nxt[e]){
            if(dis[to[e]]>dis[h.v]+v[e]){
                dis[to[e]]=dis[h.v]+v[e];
                node a;
                a.v=to[e];
                a.u=dis[to[e]];
                Q.push(a);
            }
        }
    }
    return ;
}
int x[100006];
int y[100006],z[100006];
int dis1[100006];
int main(){
    n=rd(),m=rd(),s=rd();
    for(int i=1;i<=m;i++){
        x[i]=rd(),y[i]=rd(),z[i]=rd();
        add(x[i],y[i],z[i]);
    }
    memset(dis,127,sizeof(dis));
    dij(s);
    memcpy(dis1,dis,sizeof(dis));
    memset(dis,127,sizeof(dis));
    memset(head,0,sizeof(head));
    memset(book,0,sizeof(book));
    total=0;
    for(int i=1;i<=m;i++) add(y[i],x[i],z[i]);
    dij(s);
    int ans=0;
    for(int i=1;i<=n;i++) ans=max(ans,dis[i]+dis1[i]);
    write(ans);
    return 0;
}

是x(1≤x≤N)x(1 \le x \le N)x(1xN) 的牛的农场举行的派对。有 M(1≤M≤100000)M(1\le M \le 100000)M(1M100000) 条有向道路,每条路长 Ti(1≤Ti≤100)T_i(1 \le T_i \le 100)Ti(1Ti100);每头牛都必须参加完派对后回到家,每头牛都会选择最短路径。求这 NNN 头牛的最短路径(一个来回)中最长的一条的长度。 特别提醒:可能有权值不同的重边。

猜你喜欢

转载自www.cnblogs.com/WWHHTT/p/9846973.html