这题调到后面真是调疯了.....一直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"); } }