zoukankan      html  css  js  c++  java
  • tyvj:P1467 通向聚会的道路

    背景

      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的人。

    输出格式

    第一行,即距离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 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中的数都可能出现重复数字。
    题解
    拆点+spfa。。。tyvj里面题解挺清楚的,这里就不写了,getans为什么只在偶数点里面找答案解释一下:因为初始时走过的区域为0,偶数,所以奇数点意味着这个点不是起点,所以答案不能从奇数点的dis更新得到。
      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<queue>
      5 using namespace std;
      6 #define maxn 10005
      7 #define maxm 100005
      8 #define inf 1<<29
      9 int n,m,ecnt,ans=inf,num;
     10 int pos[maxn],vis[maxn*2],dis[maxn*2],head[maxn*2];
     11 int odd[maxm],even[maxm],x[maxm],y[maxm],z[maxm];
     12 char name[maxn][20],ansch[20];
     13 struct edge{
     14     int u,v,w,next;
     15 }E[maxm*2];
     16 inline int read()
     17 {
     18     int ret(0);
     19     char ch=getchar();
     20     while(ch<'0'||ch>'9')ch=getchar();
     21     while(ch>='0'&&ch<='9')
     22     {
     23         ret=ret*10+ch-'0';
     24         ch=getchar();
     25     }
     26     return ret;
     27 }
     28 void addedge(int u,int v,int w)
     29 {
     30     E[++ecnt].u=u;
     31     E[ecnt].v=v;
     32     E[ecnt].w=w;
     33     E[ecnt].next=head[u];
     34     head[u]=ecnt;
     35 }
     36 void add()
     37 {
     38     for(int i=1 ; i<=m ; ++i )
     39     {
     40         if(odd[i])addedge(y[i],x[i]+n,z[i]);
     41         if(even[i])addedge(y[i]+n,x[i],z[i]);
     42         if((odd[i]|even[i])==0)
     43         {
     44             addedge(y[i],x[i]+n,z[i]);
     45             addedge(y[i]+n,x[i],z[i]);
     46         }
     47     }
     48 }
     49 void spfa()
     50 {
     51     queue<int> q;
     52     memset(dis,127/3,sizeof(dis));
     53     vis[n]=vis[n<<1]=1;
     54     dis[n]=dis[n<<1]=0;
     55     q.push(n);
     56     q.push(n+n);
     57     while(!q.empty())
     58     {
     59         int d=q.front();q.pop();
     60         vis[d]=0;
     61         for(int i=head[d] ; i ; i=E[i].next )
     62         {
     63             int v=E[i].v;
     64             int w=E[i].w;
     65             if(dis[v]>dis[d]+w)
     66             {
     67                 dis[v]=dis[d]+w;
     68                 if(!vis[v])
     69                 {
     70                     vis[v]=1;
     71                     q.push(v);
     72                 }
     73             }
     74         }
     75     }
     76 }
     77 void getans()
     78 {
     79     for(int i=1 ; i<=num ; ++i )
     80     {
     81         if(dis[pos[i]]<ans)
     82         {
     83             ans=dis[pos[i]];
     84             memcpy(ansch,name[i],sizeof(name[i]));
     85         }
     86         if(dis[pos[i]]==ans)
     87             if(ansch>name[i])
     88                 memcpy(ansch,name[i],sizeof(name[i]));
     89     }
     90     puts(ansch);
     91     printf("%d",ans);
     92 }
     93 int main()
     94 {
     95     int k;
     96     scanf("%d%d",&n,&m);
     97     for(int i=1 ; i<=m ; ++i ){x[i]=read();y[i]=read();z[i]=read();}
     98     scanf("%d",&num);
     99     for(int i=1 ; i<=num ; ++i ){k=read();odd[k]=1;}
    100     scanf("%d",&num);
    101     for(int i=1 ; i<=num ; ++i ){k=read();even[k]=1;}
    102     scanf("%d",&num);
    103     for(int i=1 ; i<=num ; ++i )
    104     {
    105         pos[i]=read();
    106         scanf("%s",name[i]);
    107     }
    108     add();
    109     spfa();
    110     getans();
    111     return 0;
    112 }
  • 相关阅读:
    hello world!
    react(一):组件的生命周期
    position和BFC
    继承
    绕不开的this
    js世界这么大,闭包想看看
    js中数组常用方法总结
    Appium混合应用测试
    手机APP兼容性测试
    运行monitor提示需要安装旧JAVA SE 6运行环境
  • 原文地址:https://www.cnblogs.com/fujudge/p/7506509.html
Copyright © 2011-2022 走看看