cogs 22. [HAOI2005] 路由选择问题

22. [HAOI2005] 路由选择问题

★★★   输入文件:route.in   输出文件:route.out   简单对比
时间限制:1 s   内存限制:128 MB

【问题描述】

    X城有一个含有N个节点的通信网络,在通信中,我们往往关心信息从一个节点I传输到节点J的最短路径。遗憾的是,由于种种原因,线路中总有一些节点会出故障,因此在传输中要避开故障节点。
任务一:在己知故障节点的情况下,求避开这些故障节点,从节点I到节点J的最短路径S0。
任务二:在不考虑故障节点的情况下,求从节点I到节点J的最短路径S1、第二最短路径S2。

【输入文件】

第1行: N I J (节点个数 起始节点 目标节点)
第2—N+1行: Sk1 Sk2…SkN (节点K到节点J的距离为SkJ K=1,2,……,N)
最后一行: P T1 T2……Tp (故障节点的个数及编号)

【输出文件】

S0 S1 S2 (S1<=S2 从节点I到节点J至少有两条不同路径)

【输入输出样例】

route.in

5 1 5
0 10 5 0 0
10 0 0 6 20
5 0 0 30 35
0 6 30 0 6
0 20 35 6 0
1 2

route.out

40 22 30

【约束条件】

(1)N<=50 N个节点的编号为1,2,…,N
(2)Skj为整数,Skj<=100,(K,J=1,2…,N 若Skj=0表示节点K到节点J没线路)
(3)P<=5  

思路:先跑一个最短路再跑一个次短路,然后把有故障的点和与之相连的边删去,最后再跑一个最短路。

错因:题目中的路径为简单路,然而,我并没有考虑这一点。

#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 1000
#define INF 0x3f3f3f3f
using namespace std;
struct nond{
    int g,f,to,vis[MAXN];
    bool operator<(const nond &r) const {
        if(r.f==f)    return r.g<g;
        else return r.f<f;
    }
}tmp,opt;
int n,s,t,p,cnt,tot,tot1,ans1,ans2,ans3;
int dis[MAXN],vis[MAXN],map[MAXN][MAXN];
int to[MAXN],head[MAXN],net[MAXN],cap[MAXN];
int to1[MAXN],head1[MAXN],net1[MAXN],cap1[MAXN];
void add(int u,int v,int w){
    to[++tot]=v;net[tot]=head[u];cap[tot]=w;head[u]=tot;
    to1[++tot1]=u;net1[tot1]=head1[v];cap1[tot1]=w;head1[v]=tot1;
}
void spfa(int s){
    queue<int>que1;
    for(int i=0;i<=n;i++)    dis[i]=INF;
    que1.push(s);
    vis[s]=1;dis[s]=0;
    while(!que1.empty()){
        int now=que1.front();
        que1.pop();
        vis[now]=0;
        for(int i=head1[now];i;i=net1[i])
            if(dis[to1[i]]>dis[now]+cap1[i]){
                dis[to1[i]]=dis[now]+cap1[i];
                if(!vis[to1[i]]){
                    vis[to1[i]]=1;
                    que1.push(to1[i]);
                }
            }
    }
}
int Astar(int kk){
    priority_queue<nond>que;
    if(s==t)    kk++;
    if(dis[s]==INF)    return -1;
    tmp.g=0;
    tmp.to=s;
    tmp.f=dis[s];
    que.push(tmp);
    while(!que.empty()){
        tmp=que.top();
        que.pop();
        if(tmp.to==t)    cnt++;
        if(cnt==kk)    return tmp.g;
        for(int i=head[tmp.to];i;i=net[i]){
            if(tmp.vis[to[i]])    continue;
            opt=tmp;
            opt.to=to[i];
            opt.g=tmp.g+cap[i];
            opt.f=opt.g+dis[to[i]];
            opt.vis[to[i]]=1;
            que.push(opt);
        }
    }
    return -1;
}
int main(){
    freopen("route.in","r",stdin);
    freopen("route.out","w",stdout);
    scanf("%d%d%d",&n,&s,&t);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
            int x;
            scanf("%d",&x);
            map[i][j]=x;
            if(x!=0)    add(i,j,x);
        }
    spfa(t);
    ans1=dis[s];
    for(int i=2;i<=n;i++){
        cnt=0;
        int bns=Astar(i);
        if(bns!=dis[s]){
            ans2=bns;
            break;
        }
    }
    memset(vis,0,sizeof(vis));
    memset(dis,0,sizeof(dis));
    memset(to1,0,sizeof(to1));
    memset(cap1,0,sizeof(cap1));
    memset(net1,0,sizeof(net1));
    memset(head1,0,sizeof(head1));
    tot1=0;
    scanf("%d",&p);
    for(int i=1;i<=p;i++){
        int x;
        scanf("%d",&x);
        for(int j=1;j<=n;j++)
            map[x][j]=map[j][x]=0;
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(map[i][j])    add(i,j,map[i][j]);
    spfa(t);
    ans3=dis[s];
    printf("%d %d %d",ans3,ans1,ans2);
}

 

posted @ 2017-08-22 16:05  一蓑烟雨任生平  阅读(255)  评论(0编辑  收藏  举报