这题调到后面真是调疯了.....一直wa啊wa................卧槽, 尼玛的原来是手敲队列的时候, 队列大小开小了, 因为spfa一个结点能多次进入队列......这他妈都能错........卧槽...........
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
inline int Rint() { int x; scanf("%d", &x); return x; }
inline int max(int x, int y) { return (x>y)? x: y; }
inline int min(int x, int y) { return (x<y)? x: y; }
#define FOR(i, a, b) for(int i=(a); i<=(b); i++)
#define FORD(i,a,b) for(int i=(a);i>=(b);i--)
#define REP(x) for(int i=0; i<(x); i++)
typedef __int64 int64;
//#define INF (1<<30)
const int64 INF = 0x7f7f7f7f7f7f7f7f;
const double eps = 1e-8;
#define bug(s) cout<<#s<<"="<<s<<" "
#define MAXN (1316*4)
#define MAXM (13522*2)
struct node { int u, v, w; }a[MAXM];
int idx;
int head[MAXN], next[MAXM];
void init() { idx=0; memset(head, -1, sizeof(head)); }
void addedge(int u, int v, int w) { a[idx].u=u; a[idx].v=v; a[idx].w=w; next[idx]=head[u]; head[u]=idx++; }
int n, m;
int q[MAXN*10]; // 不是MAXN!!!因为一个点可以多次进入队列!!!............WA到死
int front, tail;
int inq[MAXN]; //在队中就不用再加了. //这其实是bfs的变种
int64 step[MAXN]; //维护步数
int64 dist[MAXN]; // st->i
void spfa(int st)
{
memset(step, 0, sizeof(step));
memset(inq, 0, sizeof(inq));
FOR(i, 1, n) //1-th
dist[i] = i==st? 0: INF;
front = tail = 0;
q[tail++] = st;
inq[st] = 1;
while(front<tail)
{
int u = q[front++]; //别忘了 front++, pop
inq[u] = 0;
for(int e=head[u]; e!=-1; e=next[e])
{
int v = a[e].v;
if(dist[u]<INF && ( dist[v]>dist[u]+a[e].w || (dist[v]==dist[u]+a[e].w && step[u]+1>step[v]) ) ) //重点: 在最短路相等时, 选边数最多的!!!
{
step[v] = step[u]+1;
dist[v] = dist[u]+a[e].w;
//bug(v);bug(dist[v])<<endl;
if(!inq[v])
{
q[tail++] = v;
inq[v] = 1;
}
}
}
}
}
int main()
{
int T = Rint();
FOR(ca, 1, T)
{
printf("Case %d: ", ca);
init(); //清图
n = Rint();
m =Rint();
REP(m)
{
int u = Rint(), v=Rint(), w=Rint(); //1-th
char id[2]; scanf("%s", id);
// LOVE i, i+n, i+2n, i+3n.
switch(id[0])
{
case 'L':
addedge(u+3*n, v, w);
addedge(v+3*n, u, w);
break;
case 'O':
addedge(u, v+n, w);
addedge(v, u+n, w);
break;
case 'V':
addedge(u+n, v+2*n, w);
addedge(v+n, u+2*n, w);
break;
case 'E':
addedge(u+2*n, v+3*n, w);
addedge(v+2*n, u+3*n, w);
break;
}
}
if(n == 1) //特判
{
int64 ans = 0;
int find = 1;
FOR(u, 1, 4) //枚举4个点
{
int64 minx = INF;
for(int e=head[u]; e!=-1; e=next[e]) //枚举邻边
{
if(minx>a[e].w) minx = a[e].w;
}
if(minx == INF) { find=0; break; }
ans+=minx;
}
if(find)
{
printf("Cute Sangsang, Binbin will come with a donkey after travelling %I64d meters and finding %d LOVE strings at last.\n", ans, 1);
}
else
printf("Binbin you disappoint Sangsang again, damn it!\n");
continue;
}
int tn = n;
n*=4;
m = idx;
spfa(1+3*tn);
if(dist[tn*4]<INF) //题目要求必须走完整的 LOVE.
printf("Cute Sangsang, Binbin will come with a donkey after travelling %I64d meters and finding %I64d LOVE strings at last.\n", dist[tn*4], step[tn*4]/4);
else
printf("Binbin you disappoint Sangsang again, damn it!\n");
}
}