Hdu 2145 zz's Mysterious Present 解题分析

来源:互联网 发布:java百度云资源 编辑:程序博客网 时间:2024/06/13 19:57

题意:输入城市数n, 朋友数m,道路数k,再输入k条路,zz所在城市编号,m个朋友的城市编号,m个朋友的速度。最快到达zz所在城市的朋友得到礼物,若同时到时距离远的朋友得到礼物,若同时到距离也相同时编号大的朋友得到礼物。本题主要解题思路是求最短路径,然后找最小值。注意是有向图。

本题2个可能的Bug,(1)可能m>n;(2)第一个朋友可能肯定可以到达zz所在城市。

本题用m次Dijkstra要超时,怎么办?处理技巧:把终点做起点,所有边反方向处理。

#include<iostream>
#include<vector>
using namespace std;
 
const int MAX=30001; //根据题目算出
 
vector <vector <int> > mat;
vector <bool> visited;
vector <int> dist;
int n;
 
int minVertex()
{
    int next=-1;
    for (int i=0;i<n;i++)
        if (!visited[i] && (next==-1 || dist[i]<dist[next]))
   next=i;          
    return next;
}
 
struct Who
{
    double t;//为便于写比较函数
    int p;
    int id;
};
 
bool cmp(Who a,Who b)
{
    if (a.t==b.t)
    {
        if (dist[a.p]==dist[b.p])//注意是距离的比较
            return a.id>b.id;
        else
            return dist[a.p]>dist[b.p];
    }
    else
        return a.t<b.t;
}
 
void Dijkstra(int source)
{
    dist=mat[source];
    fill(visited.begin(),visited.end(),false);
    visited[source]=true;
    while(true)
    {
        int next=minVertex();
        if (next==-1) break;
        visited[next]=true;
     
        for (int i=0; i<n; i++)
            if (!visited[i] && dist[i]>mat[next][i]+dist[next])
                dist[i]=mat[next][i]+dist[next];
    }
}
 
bool run()
{
    int m,k,i;    
    if(scanf("%d%d%d",&n,&m,&k)==EOF) return false;
 
    mat.resize(n);
    for(i=0;i<n;i++)
    {
        mat[i].resize(n);
        fill(mat[i].begin(),mat[i].end(),MAX);
        mat[i][i]=0;
    }
   
    for( i=0;i<k;i++)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        a--;
        b--;
        mat[b][a]=c;//反方向处理
    }
 
    int start;
    scanf("%d",&start);
    start--;
    visited.resize(n);
    Dijkstra(start);
 
    vector <int> p(m);
    vector <int> speed(m);
   
    for(i=0;i<m;i++)
    {
        scanf("%d",&p[i]);
        p[i]--;
    }
 
    for(i=0;i<m;i++)
    {
        scanf("%d",&speed[i]);
    }
 
    Who r={INT_MAX,0,0};  //假设时间不超过INT_MAX
    int cnt=0;   //其实这个变量可以不要的
    for(i=0;i<m;i++)
    {
        if (dist[p[i]]!=MAX)
        {
            Who w;
            w.t=dist[p[i]]*1.0/speed[i];
            w.id=i+1;
            w.p=p[i];
            if(cmp(w,r)==true) r=w;
        }
        else
        {       
            cnt++;
        }       
    }
 
    if (cnt==m)
        printf("No one/n");
    else     
        printf("%d/n",r.id);   
 
    return true;
}
 
int main()
{
   while(run());
   return 0;
}

原创粉丝点击