QBXT 2017 春季赛P4749 F’s problem(f)

来源:互联网 发布:深圳蜂窝网络 编辑:程序博客网 时间:2024/03/28 21:26

清北学堂2017NOIP冬令营入学测试P4749 F’s problem(f)

时间: 1000ms / 空间: 655360KiB / Java类名: Main

背景

冬令营入学测试

描述

这个故事是关于小F的,它有一个怎么样的故事呢。

         小F是一个田径爱好者,这天它们城市里正在举办马拉松比赛,这个城市可以被看作是n个点m条带权有向边组成的图。马拉松比赛的终点只有一个:点S。

         有k个人参加了这场马拉松,小F所在的城市的马拉松与正常的马拉松不一样,每个人的起点都是不相同的,具体地,第i个人从第{ai}个城市出发,并且第i个人的速度是{vi}。每个人当然是会沿着最短路跑到S点,如果一个人跑步的距离是s,速度是v,那么他所花费的时间为s/v。

         现在小F想知道,谁是最快到达终点的。若有多个同时到达终点的,就求跑的路最长的,如果有多个同时到达终点且跑的路最长的,就求编号最大的。

         小F想知道那个人的编号是多少。

输入格式

第一行3个数字,n,k,m,表示点的个数,跑步的人数,以及路径的条数。

         接下来一行m行,每行3个数ai,bi,ci表示有一条从ai到bi长为ci的有向路径。

         接下来一行一个数S。

         接下来一行k个数,表示每个人的起点xi。

         接下来一行k个数,表示每个人的速度vi。

输出格式

输出一个数表示答案。

测试样例1

输入

5 2 10 
5 1 9 
1 2 81 
2 3 30 
2 1 46 
1 4 45 
2 4 48 
5 1 93 
2 5 61 
2 5 21 
3 5 45 

3 5 
18 29

输出

2

备注

输入样例

3 2 3

1 2 2

1 3 3

2 3 1

3

2 1

1 3

输出样例

2

数据范围

对于30%的数据n<=5,m<=10。

对于100%的数据n<=300,m<=5000。0<=ci<=100,1<=xi,S<=n,1<=vi<=100,1<=k<=n。

最短路  建反边~~~

#include<iostream>#include<cstring>#include<cstdio>#include<queue>using namespace std;#define maxn 305struct Edge{int u,v,w,next;}e[6600];int dis[maxn],n,m,k,v[maxn],s[maxn],head[maxn],tot,S;queue<int>q;double time[maxn];int mark;// 答案标记 bool exist[maxn];void Add_Edge(int u,int v,int w){tot++;e[tot].v=v;e[tot].w=w;e[tot].next=head[u];head[u]=tot;}void SPFA(){memset(dis,0x3f,sizeof dis );memset(exist,0,sizeof exist );q.push(S);exist[S]=1;dis[S]=0;while(!q.empty()){int u=q.empty();q.pop();exist[u]=0;for(int i=head[u];i;i=e[i].next){int v=e[i].v,w=e[i].w;if(dis[v]>dis[u]+w){dis[v]=dis[u]+w;if(!exist[v]){q.push(v);exist[v]=1;}}}}}void Solve(){//以为我们是从1到K读入所以mark标记的一定是满足答案中的最大的人物编号 for(int i=1;i<=k;i++){        scanf("%d",&v[i]);        time[i]=(double)dis[s[i]]/v[i];        if(mark){            double h=time[i]-time[mark];            if(h<=0.00001&&h>=0){// 时间相等                 if(dis[i]>=dis[s[mark]])//距离更大                     mark=i;            }            else if(h<0)//当前的时间花费更小                 mark=i;        }        else mark=i;     }printf("%d\n",mark);}int main(){scanf("%d%d%d",&n,&k,&m);for(int i=1,u,v,w;i<=m;i++){scanf("%d%d%d",&u,&v,&w);Add_Edge(v,u,w);}scanf("%d",&S);for(int i=1;i<=k;i++)scanf("%d",&s[i]);SPFA();Solve();return 0;}


0 0