PAT天梯赛-L2-001 紧急救援

<pre name="code" class="cpp">#include<iostream>
#include<fstream>
#include<cstring>
#include<vector>
#include<string>
#include<cstdio>

using namespace std;
const int Size=500;
const int INF=0x3f3f3f3f;
//input list
int N,M,S,D;
//temporary variables
int i,j,t;
//auxiliary vector
vector<int>RescueTeamNum;// 没觉得vector比数组好用 因题而异吧
int Matrix[Size][Size];
int Visited[Size];
int Dis[Size];
int Path[Size];
int LargestTeamNum[Size];
int PathNum[Size];

void ShortestPath_DIJ(int v0)
{
    // ********************initialize code********************
    memset(Visited,0,sizeof(Visited));
    LargestTeamNum[v0]=RescueTeamNum[v0];
    for(i=0; i<N; i++)
    {
        Dis[i]=Matrix[v0][i];
        Path[i]=-1;

        if(Dis[i]<INF){
            PathNum[i]=1;
            Path[i]=v0;
            if(i!=v0)
            LargestTeamNum[i]=RescueTeamNum[i]+RescueTeamNum[v0];
            //cout<<i<<" "<<LargestTeamNum[i]<<endl;
        }
    }
//    for(i=0; i<N; i++)
//            cout<<LargestTeamNum[i]<<endl;
//        cout<<endl;
    Path[S]=-1;
    Visited[v0]=1;
    int Min;
    int TheNearest;
    // ********************main circle********************
    for(j=1; j<N; j++){// 其余N-1个点
        Min=INF;
        for(i=0; i<N; i++)//查找 距离v0最近的点
            if(!Visited[i]&&Dis[i]<Min)
            {
                Min=Dis[i];
                TheNearest=i;
            }
        Visited[TheNearest]=1; // 将最近的点加入到最短路径的集合中去
        //LargestTeamNum[TheNearest]+=LargestTeamNum[Path[TheNearest]];
        for(i=0; i<N; i++)// 更新未加入的最短路径的集合中的其他点到v0的距离
            if(!Visited[i]&&Min+Matrix[TheNearest][i]<Dis[i])
            {
                Dis[i]=Min+Matrix[TheNearest][i];
                Path[i]=TheNearest;
                LargestTeamNum[i]=LargestTeamNum[TheNearest]+RescueTeamNum[i];
                PathNum[i]=PathNum[TheNearest];
            }
            else if(!Visited[i]&&Min+Matrix[TheNearest][i]==Dis[i])
            {
                PathNum[i]+=PathNum[TheNearest];
                if(LargestTeamNum[i] < LargestTeamNum[TheNearest]+RescueTeamNum[i])
                {
                    LargestTeamNum[i]=LargestTeamNum[TheNearest]+RescueTeamNum[i];
                    Path[i]=TheNearest;
                }
            }
    }//for
}

void PrintPath(int D)// good recursive
{
    if(Path[D]!=-1){
        PrintPath(Path[D]);
        cout<<Path[D]<<" ";
    }
}

int main()
{
    ifstream cin("in.txt");
    while(cin>>N>>M>>S>>D)
    {
        RescueTeamNum.clear();
        for(i=0; i<N; i++)
        {
            cin>>j;
            RescueTeamNum.push_back(j);
        }
        memset(Matrix,INF,sizeof(Matrix));
        int C1,C2,Len;
        for(i=0; i<M; i++)
        {
            cin>>C1>>C2>>Len;
            Matrix[C1][C2]=Matrix[C2][C1]=Len;
        }
        Matrix[S][S]=0;
        ShortestPath_DIJ(S);
//        for(i=0; i<N; i++)
//            cout<<Dis[i]<<" "<<Path[i]<<endl;
//        cout<<endl;


        cout<<PathNum[D]<<" "<<LargestTeamNum[D]<<endl;
        PrintPath(D);
        cout<<D<<endl;
    }//while
    return 0;
}

 

好久没更新了 ····

考研嘛···

就当练习数据结构了···

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值