http://acm.hdu.edu.cn/showproblem.php?pid=4360

已经很久没有碰ACM了,今后的很长一段时间也不会自己写一遍题了。有只是一天一题的小小思考,不会有多大的提高,只不过想借此来探寻自己还有多少为止的领域,以便于重新做题时能比较快地找到自己的方向。所以,这里之后的绝大部分代码都不是自己写的,而是留给自己看的。

有几个注意点:

(1)以L-O-V-E为走路方向的实现方法(数字化);

(2)在求出最短路径的情况下,如何得到最多的LOVE数目;

(3)对线段树代码的熟悉程度。

他人具体代码:

View Code
#include <iostream>
 #include <vector>
 #include <queue>
 #include <cstdio>
 using namespace std;
 const long long inf = 1ll<<57;
 const int Ni = 1320*2;
 struct node{
     int v,w,e;
     node(){}
     node(int a,int b,int c) {v=a;w=b;e=c;}
 };
 struct qnode{
     int v,e;
     qnode(){}
     qnode(int a,int b) {v=a;e=b;}
 };
 vector<node> eg[Ni];
 long long d[Ni][4];
 int num[Ni][4];
 bool vis[Ni][4];
 int n,m;
 void spfa(int s)
 {
     int i,j;
     for(i=1;i<=n;i++)
         for(j=0;j<=3;j++)
             d[i][j]=inf,num[i][j]=0,vis[i][j]=0;
     queue<qnode> q;
     int el=3,er;
     d[s][el]=0;
     vis[s][el]=1;
     q.push(qnode(s,el));
     while(!q.empty())
     {
         qnode qn=q.front(); q.pop();
         int u=qn.v;
         el=qn.e;vis[u][el]=0;
         for(i=0;i<eg[u].size();i++)
         {
             node nd=eg[u][i];
             int v=nd.v,w=nd.w;
             er=nd.e;
             if((el+1)%4==er&&(d[u][el]+w<d[v][er]||d[v][er]==0))
             {
                 d[v][er]=d[u][el]+w;
                 num[v][er]=num[u][el];
                 if(er==3) num[v][er]++;
                 if(!vis[v][er])
                 {
                     q.push(qnode(v,er));
                     vis[v][er]=1;
                 }
             }
             else if((el+1)%4==er&&(d[u][el]+w==d[v][er]||d[v][er]==0)&&num[u][el]>=num[v][er])
             {
                 num[v][er]=num[u][el];
                 if(er==3) num[v][er]++;

                 if(!vis[v][er])
                 {
                     q.push(qnode(v,er));
                     vis[v][er]=1;
                 }
             }
         }
     }
 }
 int main()
 {
     int t,cs=1;
     char str[5];
     int u,v,w;
     node nd;
     cin>>t;
     while(t--)
     {
         scanf("%d%d",&n,&m);
         for(int i=1;i<=n;i++) eg[i].clear();
         while(m--)
         {
             scanf("%d%d%d%s",&u,&v,&w,str);
             int e;if(str[0]=='L') e=0;
             else if(str[0]=='O') e=1;
             else if(str[0]=='V') e=2;
             else e=3;
             eg[u].push_back(node(v,w,e));
             eg[v].push_back(node(u,w,e));
         }
         spfa(1);
         if(d[n][3]!=inf&&d[n][3]!=0)
         printf("Case %d: Cute Sangsang, Binbin will come with a donkey after travelling %I64d meters and finding %d LOVE strings at last.\n",cs++,d[n][3],num[n][3]);
         else
         printf("Case %d: Binbin you disappoint Sangsang again, damn it!\n",cs++);
     }
     return 0;
 }