codevs 2070 爱情之路

Posted on 2016-01-22 22:11  ziliuziliu  阅读(158)  评论(0编辑  收藏  举报

满血复活。。。

这题大赞出题人。数据出的真是好。

两个要点:首先二维记录每个点每个标记的dis,然后发现有自环,果断放弃vis,然后还要判断:当距离相等但是另外一条线的挑战更多,那么还是要更新。

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<cmath>
#define maxv 1350
#define maxe 15000
#define maxn 88888888
using namespace std;
struct edge
{
int v,w,nxt,lable;
}e[maxe];
int n,m,g[maxv],x,y,t,nume=0,dis[maxv][5];
int test[maxv][5];
void addedge(int a,int b,int c,int d)
{
e[++nume].v=b;
e[nume].w=c;
e[nume].lable=d;
e[nume].nxt=g[a];
g[a]=nume;
e[++nume].v=a;
e[nume].w=c;
e[nume].lable=d;
e[nume].nxt=g[b];
g[b]=nume;
}
void spfa()
{
for (int i=1;i<=1350;i++)
for (int j=0;j<=3;j++)
dis[i][j]=maxn;
memset(test,0,sizeof(test));
queue <int> q1,q2;
for (int i=g[1];i;i=e[i].nxt)
{
if (e[i].lable==0)
{
q1.push(e[i].v);
q2.push(e[i].lable);
dis[e[i].v][0]=e[i].w;
test[e[i].v][0]=1;
}
}
while (!q1.empty())
{
int head1=q1.front(),head2=q2.front();
q1.pop();q2.pop();
for (int i=g[head1];i;i=e[i].nxt)
{
int v=e[i].v,lable=e[i].lable;
if ((dis[v][lable]>dis[head1][head2]+e[i].w) && (e[i].lable==(head2+1)%4))
{
dis[v][lable]=dis[head1][head2]+e[i].w;
test[v][lable]=test[head1][head2]+1;
q1.push(v);
q2.push(lable);
}
else if ((dis[v][lable]==dis[head1][head2]+e[i].w) && (test[v][lable]<test[head1][head2]+1))
{
test[v][lable]=test[head1][head2]+1;
q1.push(v);
q2.push(lable);
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
char la;
for (int i=1;i<=m;i++)
{
scanf("%d %d %d %c",&x,&y,&t,&la);
int u;
if (la=='L') u=0;
else if (la=='O') u=1;
else if (la=='V') u=2;
else u=3;
addedge(x,y,t,u);
}
spfa();
if (dis[n][3]==maxn) printf("HOLY SHIT!\n");
else printf("%d %d\n",dis[n][3],test[n][3]/4);
return 0;
}