PAT:1003. Emergency (25) AC

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXV=510;
const int INF=0x3fffffff;
int n,m,c1,c2;

bool vis[MAXV];
int G[MAXV][MAXV];      //城市间距离
int weight[MAXV];      //每个城市的救援人数
int d[MAXV];        //最短距离
int w[MAXV];        //可以带的最多人
int num[MAXV];        //最短路径条数


void Dijkstra(int s)
{
  memset(num,0,sizeof(num));
  memset(vis,false,sizeof(vis));
  fill(d,d+MAXV,INF);
  memset(w,0,sizeof(w));
  d[s]=0;            //本城市到本城市距离为0
  w[s]=weight[s];        //自己城市的救援队人数
  num[s]=1;          //到自己城市最短路径为1条

  for(int i=0 ; i<n ; ++i)
  {
    int MIN=INF,u=-1;
    for(int j=0 ; j<n ; ++j)  //找最小d
    {
      if(vis[j]==false && MIN>d[j])
      {
        MIN=d[j];
        u=j;
      }
    }

    if(-1==u)          //图有不连通的部分
      return;
    vis[u]=true;
    for(int v=0 ; v<n ; ++v)
    {
      if(vis[v]==false && G[u][v]!=INF)
      {
        if(d[v]>d[u]+G[u][v])
        {
          d[v]=d[u]+G[u][v];        //更新最短距离
          w[v]=w[u]+weight[v];      //更新救援人数
          num[v]=num[u];          //【warning】到新最短路径,当然是u的条数
        }
        else if(d[v]==d[u]+G[u][v])
        {
          num[v]+=num[u];          //【warning】最短路径数为u的条数+v的条数
          if(w[v]<w[u]+weight[v])
          {
            w[v]=w[u]+weight[v];    //路径相同,存入最多的救援队数量
          }
        }
      }
    }
  }
}

int main()
{
  fill(G[0],G[0]+MAXV*MAXV,INF);
  scanf("%d%d%d%d",&n,&m,&c1,&c2);
  for(int i=0 ; i<n ; ++i)      //存入每个城市救援队人数
    scanf("%d",&weight[i]);
  for(int i=0 ; i<m ; ++i)      //存入城市间距离
  {
    int u,v;
    scanf("%d%d",&u,&v);
    scanf("%d",&G[u][v]);
    G[v][u]=G[u][v];
  }
  Dijkstra(c1);
  printf("%d %d\n",num[c2],w[c2]);
  return 0;
}
posted on 2015-03-09 22:46  Evence  阅读(116)  评论(0编辑  收藏  举报