tyvj1467 通向聚会的道路
Posted shixinyi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了tyvj1467 通向聚会的道路相关的知识,希望对你有一定的参考价值。
背景
Candy住在一个被划分为n个区域的神奇小镇中,其中Candy的家在编号为n的区域,Candy生日这天,大家都急急忙忙赶去Candy家庆祝Candy的生日。
描述
Candy共有t个朋友住在不同的区域。小镇有m条道路,小镇的神奇之处在于其中的p1条道路只会在你走过区域的的个数为奇数时候开启,p2道路只会在你走过区域的个数为偶数的时候开启,剩下的道路一直都会开启。并且,所有的道路只能够单向通过。飘飘乎居士希望知道在所有的好朋友中,谁离Candy最近?。
输入格式
第一行:两个正整数n m,表示共n个区域,m条道路
接下来m行,每行三个正整数u v s表示u到v的单向道路,路程为s,其中第i条道路的编号为i。
接着一个整数p1以及p1个正整数odd[i],表示编号为odd[i]的道路只会在走过奇数个区域时开启。
接着一个整数p2以及p2个正整数even[i],表示编号为even[i]的道路只会在走过偶数个区域时开启。
接下来一个正整数 t
紧接着t行,每行一个正整数h以及一个不超过10个字符长度的字符串na(且均有小写字母组成),表示在h区域居住着名字为na的人。
接下来m行,每行三个正整数u v s表示u到v的单向道路,路程为s,其中第i条道路的编号为i。
接着一个整数p1以及p1个正整数odd[i],表示编号为odd[i]的道路只会在走过奇数个区域时开启。
接着一个整数p2以及p2个正整数even[i],表示编号为even[i]的道路只会在走过偶数个区域时开启。
接下来一个正整数 t
紧接着t行,每行一个正整数h以及一个不超过10个字符长度的字符串na(且均有小写字母组成),表示在h区域居住着名字为na的人。
输出格式
第一行,即距离candy家最近的人的名字,数据保证有且只有一个人为最后的答案。
第二行,该人到candy家的距离。
如果存在多解,则输入名字中字典序较小的一人。
第二行,该人到candy家的距离。
如果存在多解,则输入名字中字典序较小的一人。
测试样例1
输入
4 5
1 2 2
3 4 2
2 4 4
1 3 1
2 3 1
1 4
1 2
2
2 violethill
1 pink
输出
violethill
4
备注
pink尽管从1->3->4距离更近,但因为1->2的这条道路只有在走过奇数个区域时才开启,而pink此时走过的区域为偶数个(0个)(我们规定,出发点不算走第一个区域),所以pink只好沿1—>2—>3—>4,距离为5;
Violethill尽管沿2—>3—>4距离为3,但因为3—>4这条道路只有在走过偶数个区域时才开启,当violethill从2到3时,只走了奇数个(1个)区域,道路不会开启。所以,violethill只好沿2—>4这条道路行走,距离为4,所以violethill比pink更快到candy家中,并且距离为4。
对于30%的数据 0<n<=100
对于100%的数据0<n<=10000 0<m<=100000
对于所有数据保证两区域间的距离<=100000
数据保证运算即结果在maxlongint以内
数据保证输入的正确性,即至少有一个人可以到达candy家中,并且一个区域最多只有一人,不会出现相同名字的人。
友情提示:可能出现有些道路既在odd中出现,也在even中出现。并且odd或者even中的数都可能出现重复数字。
Violethill尽管沿2—>3—>4距离为3,但因为3—>4这条道路只有在走过偶数个区域时才开启,当violethill从2到3时,只走了奇数个(1个)区域,道路不会开启。所以,violethill只好沿2—>4这条道路行走,距离为4,所以violethill比pink更快到candy家中,并且距离为4。
对于30%的数据 0<n<=100
对于100%的数据0<n<=10000 0<m<=100000
对于所有数据保证两区域间的距离<=100000
数据保证运算即结果在maxlongint以内
数据保证输入的正确性,即至少有一个人可以到达candy家中,并且一个区域最多只有一人,不会出现相同名字的人。
友情提示:可能出现有些道路既在odd中出现,也在even中出现。并且odd或者even中的数都可能出现重复数字。
题目有毒!!!可能出现有些道路既在odd中出现,也在even中出现,意思是一直开启而不是由于条件矛盾而都不开启。
由于这个我一直WA三个点还以为自己又犯了什么智障错误要写手打堆了呢。。。
我们把有奇数限制的边叫为奇边,有偶数限制的边叫为偶边,没有限制(既在odd中出现,也在even中出现或都没出现)的边拆成一条奇边和一条偶边。
我们把每个区域分成两个点,一个为入边为奇边,出边为偶边的,一个为入边为偶边,出边为奇边的,然后反向建图spfa。
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> using namespace std; #define ull unsigned long long const int maxn=2e4+10,maxm=2e5+10; const ull INF=-1; int n,m; int mu[maxm],mv[maxm]; ull ms[maxm],ans=INF; bool modd[maxm],meven[maxm]; ull aa;char cc; ull read() { aa=0;cc=getchar(); while(cc<‘0‘||cc>‘9‘) cc=getchar(); while(cc>=‘0‘&&cc<=‘9‘) aa=aa*10+cc-‘0‘,cc=getchar(); return aa; } struct Pp{ int x;string s; }pp[maxn]; bool cmp(const Pp &a,const Pp &b) { return a.s<b.s; } int fir[maxn],nxt[maxm],to[maxm],e=0;ull v[maxm]; void add(int y,int x,int z) { to[++e]=y;nxt[e]=fir[x];fir[x]=e;v[e]=z; } ull dis[maxn]; int zz[maxn]; bool vis[maxn]; void spfa(int st){ memset(dis,-1,sizeof(dis)); int s=1,t=0,x,y,z; dis[st]=0;zz[++t]=st;vis[st]=1; while(s<=t) { x=zz[s%maxn];s++;vis[x]=0; for(y=fir[x];y;y=nxt[y]) { z=to[y]; if(dis[z]<=dis[x]||dis[z]<=dis[x]+v[y]) continue; dis[z]=dis[x]+v[y]; if(!vis[z]) { vis[z]=1;t++; zz[t%maxn]=z; } } } } int main() { n=read();m=read(); for(int i=1;i<=m;++i) { mu[i]=read();mv[i]=read(); ms[i]=read(); } int x=read(),y; for(int i=1;i<=x;++i) { y=read();modd[y]=1; } x=read(); for(int i=1;i<=x;++i) { y=read();meven[y]=1; } for(int i=1;i<=m;++i) { if(!modd[i]) add(mu[i],mv[i]+n,ms[i]); if(!meven[i]) add(mu[i]+n,mv[i],ms[i]); if(modd[i]&&meven[i]) { add(mu[i]+n,mv[i],ms[i]); add(mu[i],mv[i]+n,ms[i]); } } add(n,2*n+1,0);add(2*n,2*n+1,0); x=read(); for(int i=1;i<=x;++i) { pp[i].x=read(); cin>>pp[i].s; } sort(pp+1,pp+x+1,cmp); spfa(2*n+1);y=0; for(int i=1;i<=x;++i) { if(dis[pp[i].x]<ans) { y=i;ans=dis[pp[i].x]; } } cout<<pp[y].s<<"\n"; cout<<ans; return 0; }
以上是关于tyvj1467 通向聚会的道路的主要内容,如果未能解决你的问题,请参考以下文章
通向膨胀的道路(关于 “separation of concerns” (SoC)的原则)