双向存图解题

P1629 邮递员送信 

P1342 请柬 

P1821[USACO07FEB]银牛派对Silver Cow Party

都是求的往返的最大,最小路径,用堆优化的dijkstra跑两遍就行,都是板子题

银牛派对的代码:

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

int dis1[1002],dis2[1002],hd1[1002],hd2[1009];
bool vis[1009];
int tot,n,m,s,maxn;
struct llo{
    int to,nxt,w;
} e1[100002],e2[100002];
void add(int fr,int to,int w){
    tot++;
    e1[tot]=(llo){to,hd1[fr],w};
    hd1[fr]=tot;
    e2[tot]=(llo){fr,hd2[to],w};
    hd2[to]=tot;
}
struct heap{
    int u,d;
    friend bool operator <(heap x,heap y){
        return x.d>y.d;
    }
};
void diji1(int s){
    memset(dis1,0x7f,sizeof(dis1));
    memset(vis,0,sizeof(vis));
    priority_queue <heap> q;
    dis1[s]=0;
    q.push((heap){s,0});
    while(!q.empty()){
        int u=q.top().u;q.pop();
        if(vis[u])    continue;
        vis[u]=1;
        for(int i=hd1[u];i;i=e1[i].nxt){
            int v=e1[i].to;
            if(dis1[v]>dis1[u]+e1[i].w){
                dis1[v]=dis1[u]+e1[i].w;
                if(!vis[v])
                    q.push((heap){v,dis1[v]});
            }
        }
    }
}
void diji2(int s){
    memset(dis2,0x7f,sizeof(dis2));
    memset(vis,0,sizeof(vis));
    priority_queue <heap> q;
    dis2[s]=0;    
    q.push((heap){s,0});
    while(!q.empty()){
        int u=q.top().u;q.pop();
        if(vis[u])    continue;
        vis[u]=1;
        for(int i=hd2[u];i;i=e2[i].nxt){
            int v=e2[i].to;
            if(dis2[v]>dis2[u]+e2[i].w){
                dis2[v]=dis2[u]+e2[i].w;
                if(!vis[v])
                    q.push((heap){v,dis2[v]});
            }
        }
    }
}
int main(){
    scanf("%d%d%d",&n,&m,&s);
    for(int i=1;i<=m;i++){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        add(a,b,c);
    }
    diji1(s);
    diji2(s);
    for(int i=1;i<=n;i++){
        if(i==s)    continue;
        else maxn=max(maxn,dis1[i]+dis2[i]);
    }
    printf("%d",maxn);
    return 0;
} 
View Code
原文地址:https://www.cnblogs.com/jindui/p/11215651.html