129 条题解
- 
  6PowderHan LV 10 @ 2017-05-04 08:13:10 Accepted 
 /in/foo.cc: In function 'void check()':
 /in/foo.cc:127:5: warning: suggest explicit braces to avoid ambiguous 'else' [-Wparentheses]
 if(!vis[i])
 ^状态 耗时 内存占用#1 Accepted 2ms 2.59MiB 
 #2 Accepted 6ms 2.582MiB
 #3 Accepted 2ms 2.59MiB
 #4 Accepted 5ms 2.715MiB
 #5 Accepted 22ms 2.602MiB
 #6 Accepted 18ms 2.625MiB
 #7 Accepted 23ms 2.723MiB好题啊 
 陷阱蛮多的Orz
 提供了一些新的套路23333
 第一眼看过去 觉得是个SPFA裸题啊
 后面感觉不对 没这么简单
 出题人黑良心
 当输入的图不是连通图时,SPFA(s)能做的就只是找出源点s所在的连通分量中的负环而已。
 也就是说如果图中存在环,但不在源点所在的连通分量内的话,就会输出一堆的NoPath,
 而不是-1,从此WA没救。
 解决方案:
 添加一个数组vis,来确定某个点是否访问过
 (因为如果不在源点的连通分量内的点在SPFA的过程中时不会访问到的)。
 然后每一个没有访问过的点都来一遍SPFA,以此来检查是否存在负环。
 每次SPFA完了之后再将每个在这一次SPFA中 访问过的点的vis设为true,判断的标准:
 是否进入过队列。
 小优化:
 dist[source]< 0 那么就存在负环,因为dist[source]本来为0,
 结果跑了一圈成负的了,那说明有负环。
 首先我们看到我们要先处理有没有负权环的问题
 这个明显要独立做出来
 就是我们先定一个vis数组标记点是否访问过
 然后每次对于一个未访问的点
 SPFA一下 并在SPFA中把到过的点标记访问过
 那么我们可以知道 如果和这个点连通】
 那么一定就是能走到(能标记到访问)
 所以我们下一次就直接从没有访问过的点继续SPFA
 即我们一次SPFA可以处理掉一个SCC中是否有负权环的问题
 然后一直SPFA完所有的强连通分量
 然后处理完后确定没有环了
 我们就可以进行正常的SPFA求出最短路了
 Orz因为怕麻烦啊
 SPFA两种(一种要用到vis一种不要用到vis)就合在一起了
 所以检查完负权环后
 就要将vis数组清为0防止被SPFA中的判断vis误伤啊
 然后就可以直接暴力做了
 裸的SPFA好激动啊
 注意一下这里SPFA中的小优化
 上面也说了
 嗯挺好用的Orz
 好题
 处理负权边和不连通问题
 QAQ
 随便读入优化一下飞快#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <queue> #include <stack> using namespace std; char rd; int pn; template<typename Type> inline void read(Type& v) { pn=1; while((rd=getchar())<'0'||rd>'9') if(rd=='-') pn=-1; v=rd-'0'; while((rd=getchar())>='0'&&rd<='9') v=v*10+rd-'0'; v*=pn; } template<typename Type> inline void out(Type v,bool c=1) { if(v==0) putchar(48); else { if(v<0) { putchar('-'); v=-v; } int len=0,dg[20]; while(v>0) { dg[++len]=v%10; v/=10; } for(int i=len;i>=1;i--) putchar(dg[i]+48); } if(c) putchar('\n'); else putchar(' '); } const int MAXN=1005; const int MAXM=200005; const int INF=0x7fffffff; struct Edge { int to,w,nxt; Edge() { to=nxt=-1; w=0; } }e[MAXM]; int fisrt[MAXN]; int tot; int n,m,s; inline void Add_Edge(int u,int v,int w) { e[++tot].to=v; e[tot].w=w; e[tot].nxt=fisrt[u]; fisrt[u]=tot; } void init() { memset(fisrt,-1,sizeof(fisrt)); read(n); read(m); read(s); int u,v,w; for(int i=1;i<=m;i++) { read(u); read(v); read(w); Add_Edge(u,v,w); } } bool vis[MAXN],inq[MAXN]; int cnt[MAXN]; int dis[MAXN]; queue<int> q; bool spfa(int s) { for(int i=1;i<=n;i++) dis[i]=INF; memset(inq,0,sizeof(inq)); memset(cnt,0,sizeof(cnt)); while(!q.empty()) q.pop(); dis[s]=0; q.push(s); inq[s]=1; while(!q.empty()) { int u=q.front(); q.pop(); inq[u]=0; if(dis[s]<0) return 0; for(int i=fisrt[u];i!=-1;i=e[i].nxt) { int& v=e[i].to; int& w=e[i].w; if(vis[v]) continue; if(dis[v]>dis[u]+w) { dis[v]=dis[u]+w; if(!inq[v]) { q.push(v); inq[v]=1; } if(++cnt[v]>n) return 0; } } } for(int i=1;i<=n;i++) vis[i]=vis[i]||cnt[i]; return 1; } void check() { for(int i=1;i<=n;i++) if(!vis[i]) if(!spfa(i)) { cout<<-1<<endl; exit(0); } else continue; } void work() { memset(vis,0,sizeof(vis)); spfa(s); for(int i=1;i<=n;i++) if(dis[i]==INF) cout<<"NoPath"<<endl; else out(dis[i]); } int main() { init(); check(); work(); return 0; }**code by PowderHan**
- 
  4@ 2017-10-16 18:50:39额,图连不连通怎么判?加一个超级源,将它与每个点连一条权值为0的边,跑一边spfa即可 
 // vijos P1053#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #define ins(u,v,w){e[++cnt]=(edge){v,h[u],w};h[u]=cnt;} using namespace std; const int N=1e3+5,M=1e5+5,inf=1e9+5; inline int read(){ int x=0,f=1,c=getchar(); for(;c< '0'||c >'9';c=getchar())if(c=='-')f=-1; for(;c>='0'&&c<='9';c=getchar())x=x*10+c-48; return x*f; } int n,m,s,u,v,w; struct edge{int to,nxt,w;}e[M+N]; int h[N],cnt; inline void lop(int &x){if(++x==N) x=1;} int q[N],head,tail,d[N],nc[N];bool inq[N]; bool spfa(int s){ head=tail=0; for(int i=1;i<=n;++i) d[i]=inf,inq[i]=nc[i]=0; q[tail]=s;inq[s]=nc[s]=1;lop(tail);d[s]=0; while(head!=tail){ int u=q[head];inq[u]=0;lop(head); for(int i=h[u];i;i=e[i].nxt) if(d[e[i].to]>d[u]+e[i].w){ d[e[i].to]=d[u]+e[i].w; if(!inq[e[i].to]){ inq[e[i].to]=1;q[tail]=e[i].to;lop(tail); if(++nc[e[i].to]>n) return false; } } } return true; } int main(){ n=read();m=read();s=read(); for(int i=1;i<=m;++i){ u=read();v=read();w=read(); if(u==v&&w<0) {puts("-1");return 0;} if(u!=v) ins(u,v,w); } int ss=n+1; for(int i=1;i<=n;++i) ins(ss,i,0); if(!spfa(ss)) {puts("-1");return 0;} spfa(s); for(int i=1;i<=n;++i){ if(d[i]>=inf) puts("NoPath"); else printf("%d\n",d[i]); } return 0; }
- 
  2@ 2016-06-09 12:20:10裸奔弗洛伊德 
 ```c++
 记录信息
 评测状态 Time Limit Exceeded
 题目 P1053 Easy sssp
 递交时间 2016-06-09 12:14:34
 代码语言 C++
 评测机 ShadowShore
 消耗时间 6481 ms
 消耗内存 5408 KiB
 评测时间 2016-06-09 12:14:41
 评测结果
 编译成功测试数据 #0: Accepted, time = 0 ms, mem = 5404 KiB, score = 0 
 测试数据 #1: TimeLimitExceeded, time = 1015 ms, mem = 5392 KiB, score = 0
 测试数据 #2: TimeLimitExceeded, time = 1140 ms, mem = 5408 KiB, score = 0
 测试数据 #3: TimeLimitExceeded, time = 1015 ms, mem = 5396 KiB, score = 0
 测试数据 #4: TimeLimitExceeded, time = 1015 ms, mem = 5392 KiB, score = 0
 测试数据 #5: Accepted, time = 1265 ms, mem = 5408 KiB, score = 25
 测试数据 #6: TimeLimitExceeded, time = 1031 ms, mem = 5396 KiB, score = 0
 TimeLimitExceeded, time = 6481 ms, mem = 5408 KiB, score = 25
 代码
 #include <cstdio>
 #include <cstring>
 using namespace std;
 const int INF = 0xfffff,maxn = 1001;
 long n,m,start,v[maxn][maxn];
 bool s[maxn][maxn];
 void input()
 {
 memset(s,false,sizeof(s));
 scanf("%ld %ld %ld",&n,&m,&start);
 for (int i = 1;i <= n;i++)
 for (int j = 1;j <= n;j++)
 v[i][j] = INF;
 for (int i = 1,a,b,c;i <= m;i++)
 {
 scanf("%d %d %d",&a,&b,&c);
 v[a][b] = c;
 s[a][b] = true;
 }
 }
 #include <algorithm>
 void floyd()
 {
 for (int k = 1;k <= n;k++)
 for (int i = 1;i <= n;i++)
 for (int j = 1;j <= n;j++)
 v[i][j] = min(v[i][j],v[i][k] + v[k][j]);
 }
 void work()
 {
 floyd();
 for (int i = 1;i <= n;i++)
 v[i][i] = 0;
 for (int k = 1;k <= n;k++)
 for (int i = 1;i <= k-1;i++)
 for (int j = i+1;j <= k-1;j++)
 if (s[i][j] && s[j][k] && v[k][i])
 if(v[i][j]+v[j][k]+v[k][i] < 0)
 {
 printf("-1");
 exit(0);
 }
 }
 void output()
 {
 for (int i = 1;i <= n;i++)
 if (v[start][i] == INF)
 printf("NoPath");
 else
 printf("%ld\n",v[start][i]);
 }
 int main()
 {
 input();
 work();
 output();
 return 0;
 }
 ```
- 
  1@ 2016-01-30 21:48:30本题看起来比较简单,题目也比较清楚,但是隐藏了很多陷阱,首先此题要求找负环,如果有输出-1,如果没有输出S到所有边的距离。 
 建图很简单,数据范围__N<=1000__,直接用矩阵存入。
 但是此题的边__有重复__!,建边的时候要注意选最小的。(用邻接表存有点麻烦)
 点若入队>=n次或__dist[出发点]<0__则有负环,对每个点SPFA求负环绝对超时。
 所以用__Swim数组__储存经过的点,下次求负环时直接跳过标记的点。
 ###code
 #include <iostream>
 #include <cstdio>
 #include <cstring>
 #include <queue>
 using namespace std;
 #define INF 0x7f7f7f
 #define MAX1 1010
 #define MAX2 100010int N,M,S; struct sssp{ 
 //pretreatment初始化
 void prepare(){
 for(int i=1;i<=N;i++){
 dist[i]=INF,swim[i]=false;
 for(int j=1;j<=N;j++)
 g[i][j]=INF;
 }
 }
 //set map
 int g[MAX1][MAX1];
 inline void add(int u,int v,int val){
 if(g[u][v]>val)//注意此处!数据中有重边
 g[u][v]=val;
 }
 //
 void got(int n){//建图
 for(int i=1;i<=n;i++){
 int a,b,c;
 scanf("%d%d%d",&a,&b,&c);
 add(a,b,c);
 }
 }
 //SPFA
 bool swim[MAX1];//标记已经遍历的点
 bool ins[MAX1];//入队标记
 int vis[MAX1];//记录入队次数
 int dist[MAX1];//
 queue<int> q;
 bool SPFA(int s){//SPFA
 for(int i=1;i<=N;i++) dist[i]=INF,vis[i]=0,ins[i]=false;
 while(!q.empty()) q.pop();q.push(s); 
 vis[s]++,ins[s]=true,dist[s]=0;
 while(!q.empty()){
 int t=q.front();q.pop();ins[t]=false;
 if(dist[s]<0) return true;
 for(int i=1;i<=N;i++){
 if(swim[i]==true) continue;
 int u=g[t][i];
 if(u!=INF&&dist[i]>dist[t]+u){
 dist[i]=dist[t]+u;
 if(!ins[i]){
 q.push(i);ins[i]=true,vis[i]++;
 if(vis[i]>=N/2) return true;
 }
 }
 }
 }
 for(int i=1;i<=N;i++) swim[i]=swim[i]||vis[i];
 return false;
 }bool work(){ 
 //for(int i=1;i<=N;i=i+(N/10)+1){ //随机化,减少遍历次数 i=i+(N/10)+1,但不用也可以过
 for(int i=1;i<=N;i++){
 if(!swim[i])
 if(SPFA(i)) return true;
 }
 return false;
 }
 void work_out(){
 if(work()){
 printf("-1\n");
 return;
 }
 else{
 memset(swim,0,sizeof(swim));
 SPFA(S);
 for(int i=1;i<=N;i++){
 if(dist[i]==INF) printf("NoPath\n");
 else printf("%d\n",dist[i]);
 }} 
 }
 };
 sssp car={0};int main(){ 
 scanf("%d%d%d",&N,&M,&S);
 car.prepare();
 car.got(M);
 car.work_out();return 0; 
 }
 编译成功测试数据 #0: Accepted, time = 0 ms, mem = 4276 KiB, score = 0 测试数据 #1: Accepted, time = 0 ms, mem = 4276 KiB, score = 10 测试数据 #2: Accepted, time = 15 ms, mem = 4276 KiB, score = 15 测试数据 #3: Accepted, time = 15 ms, mem = 4272 KiB, score = 15 测试数据 #4: Accepted, time = 46 ms, mem = 4276 KiB, score = 20 测试数据 #5: Accepted, time = 46 ms, mem = 4272 KiB, score = 25 测试数据 #6: Accepted, time = 62 ms, mem = 4272 KiB, score = 15 Accepted, time = 184 ms, mem = 4276 KiB, score = 100 我也是交了N次才AP! 
 鉴于没有一份详尽的题解,自己写了一份。
- 
  1@ 2009-10-14 18:20:433行代码的程序 
 无语中...
 begin
 writeln(-1);
 end.
 编译通过...
 ├ 测试数据 01:答案错误...程序输出比正确答案长
 ├ 测试数据 02:答案错误...程序输出比正确答案长
 ├ 测试数据 03:答案正确... 0ms
 ├ 测试数据 04:答案正确... 0ms
 ├ 测试数据 05:答案正确... 0ms
 ├ 测试数据 06:答案正确... 0ms
 ├ 测试数据 07:答案错误... ├ 标准行输出
 ├ 错误行输出---|---|---|---|---|---|---|---|- 
 Unaccepted 有效得分:75 有效耗时:0ms
- 
  0@ 2021-02-19 23:18:12标答(大嘘) #include <iostream> using namespace std; int main() { cout << -1 << endl; }这。。。这题真的就搞人心态,我倒是想看看点2的数据到底长啥样,因为INF写了个114514191(只到1e8,当然是自己傻x了)第二个点只要去掉dist[t] < 0就能过,加上就过不了,后来换成INF = 1e9,再在邻接矩阵处加了一个判定if (f[u][v] != INF),两者应该任取其一就能过了。血的教训啊! 思路的话,基本就是优化Bellman-Ford,先判断有没有负权环,要注意可能会有不和源点连通的块,每个之前没跑过的点都访问一次就行了,上面 青衫白叙 的超级源点感觉更优雅方便一点,懒得改了。 判断负权环: 
 1. 考虑自环,在n个点的图中,任意一点最多只能和n个点有边,那理论上限就是我经过每个边都更新一次这个点,不能更多了(吗?其实很好奇会不会有更复杂,更准确地描述),所以当一个点更新数超过n(inq_cnt[u] > n)时,直接干掉。
 2. 任意一次做Bellman-Ford时一旦出现源点dist[s] < 0,那也直接干掉。为什么?从源点出发,dist[s] < 0就是从一条路出去再回到源点,距离为负,那再重复一次同样的路线很明显会继续减小,必然是环,直接干掉。Debug: 
 1. 如之前所述,INF不能定太小或者不判定,我只能猜要不是爆精度了,要不是别的边权绝对值都很大,导致某条INF的边加那点的dist[u]还比原来的dist[v]要小;但是问题在于既然能有这样的路径被判定成负权环,为什么(inq_cnt[] > m)的判定就不会受影响呢?理论上来说,只要有被判定成负权环,迟早也会被这种方法判断到。但是仅有这个判断的时候却过了点二,非常搞笑。
 2. 前面省时间加了prev_vis[]数组,可以不用额外访问单向边指向的访问过的部分,在判定完没负权环以后还要注意memset(0)再Bellman-Ford,不然算法碰到之前标记访问过的源点直接罢工了,原地爆炸。细节挺多,抓耳挠腮。。。 #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <queue> using namespace std; const int MAXN = 1e3 + 145, INF = 1e9; int n, m, s; int f[MAXN][MAXN], dist[MAXN], inq_cnt[MAXN]; bool vis[MAXN], prev_vis[MAXN], inq[MAXN]; //Visited in this cycle; Visited in prev cycles; Nodes in queue. queue<int> q; int read() { int f = 1, x = 0; char ch = getchar(); if (ch == '-') { f = -1; ch = getchar(); } while ('0' <= ch && ch <= '9') { x *= 10; x += ch - '0'; ch = getchar(); } return f * x; } int bellmanford(int t) { for (int i = 0; i <= n; i++) { dist[i] = INF; vis[i] = false; } while (!q.empty()) q.pop(); q.push(t); dist[t] = 0; while (!q.empty()) { int u = q.front(); q.pop(); if (inq_cnt[u] > n || dist[t] < 0) return -1; vis[u] = true; inq[u] = false; for (int v = 1; v <= n; v++) { if (prev_vis[v] || f[u][v] == INF) continue; if (dist[u] + f[u][v] < dist[v]) { dist[v] = dist[u] + f[u][v]; if (!inq[v]) { q.push(v); inq_cnt[v]++; inq[v] = true; } } } } for (int i = 1; i <= n; i++) prev_vis[i] |= vis[i]; return 0; } int main() { n = read(); m = read(); s = read(); for (int u = 1; u <= n; u++) { for (int v = 1; v <= n; v++) { f[u][v] = INF; } } for (int i = 1; i <= m; i++) { int u, v, w; u = read(); v = read(); w = read(); f[u][v] = min(f[u][v], w); } int status_code = 0; for (int i = 1; i <= n; i++) { if (!prev_vis[i]) { status_code = bellmanford(i); if (status_code == -1) { cout << -1 << endl; return 0; } } } memset(prev_vis, 0, sizeof(prev_vis)); memset(inq_cnt, 0, sizeof(inq_cnt)); bellmanford(s); for (int i = 1; i <= n; i++) { if (dist[i] == INF) { cout << "NoPath" << endl; } else { cout << dist[i] << endl; } } return 0; }
- 
  0@ 2016-10-09 19:05:43原来这么多坑。。难怪AC率如此之低。 
- 
  0@ 2015-06-12 09:45:46用的如果不是Bellman-Ford,要注意此题第三个点,负权回路和源点S不连通. 
- 
  0@ 2015-01-27 22:04:27spfa,点若入队》=n次则有负环,但是正常来说如果没有负环的话,不会入队几次,所以判断条件可以稍微改少点,如n/2次 
- 
  0@ 2014-12-24 13:27:46评测结果 
 编译成功foo.pas(16,9) Warning: Variable "lalala" does not seem to be initialized 
 测试数据 #0: Accepted, time = 0 ms, mem = 8696 KiB, score = 0
 测试数据 #1: WrongAnswer, time = 0 ms, mem = 8692 KiB, score = 0
 测试数据 #2: WrongAnswer, time = 0 ms, mem = 8692 KiB, score = 0
 测试数据 #3: Accepted, time = 31 ms, mem = 8692 KiB, score = 15
 测试数据 #4: Accepted, time = 187 ms, mem = 8692 KiB, score = 20
 测试数据 #5: Accepted, time = 359 ms, mem = 8696 KiB, score = 25
 测试数据 #6: Accepted, time = 187 ms, mem = 8692 KiB, score = 15
 WrongAnswer, time = 764 ms, mem = 8696 KiB, score = 75怎么会这样... 
- 
  0@ 2014-11-07 21:24:12const 
 QN = 10000;
 var
 edges: array [1..1000,1..1000] of record y,w:longint;end;
 en: array [1..1000] of longint;
 inq: array [1..1000] of Boolean;
 f,cnt: array [1..1000] of longint;
 i,j,k,l,x,y,w,n,m: longint;
 q: array [1..10000] of longint;
 head,tail,s:longint;begin 
 assign(input, 'main.in'); reset(input);
 assign(output, 'main.out'); rewrite(output);
 read(n,m,s);
 for i := 1 to m do
 begin
 read(x,y,w);
 inc(en[x]);
 edges[x][en[x]].y:=y;
 edges[x][en[x]].w:=w;
 end;
 filldword(f,sizeof(f)>>2,maxlongint);
 head:=0;tail:=1;q[1]:=s;inq[s]:=true;cnt[s]:=1;f[s]:=0;
 while head<>tail do
 begin
 head:=head mod QN+1;
 x:=q[head];
 inq[x]:=false;
 for i := 1 to en[x] do
 begin
 j:=edges[x][i].y;
 if (f[j]>f[x]+edges[x][i].w) then
 begin
 inc(cnt[j]);
 if cnt[j]>n then
 begin
 writeln(-1);
 exit;
 end;
 f[j]:=f[x]+edges[x][i].w;
 if inq[j] then continue;
 inq[j] := true;
 tail:=tail mod QN+1;
 q[tail]:=j;
 end;
 end;
 end;
 for i := 1 to n do
 if f[i]<>maxlongint then
 writeln(f[i])
 else
 writeln('NoPath');
 close(input);
 close(output);
 end.为什么#2总过不去? 
- 
  0@ 2014-08-19 19:57:01测试数据 #0: Accepted, time = 31 ms, mem = 72204 KiB, score = 0 
 测试数据 #1: Accepted, time = 62 ms, mem = 72224 KiB, score = 10
 测试数据 #2: WrongAnswer, time = 109 ms, mem = 72224 KiB, score = 0
 测试数据 #3: Accepted, time = 31 ms, mem = 72220 KiB, score = 15
 测试数据 #4: Accepted, time = 93 ms, mem = 72216 KiB, score = 20
 测试数据 #5: TimeLimitExceeded, time = 5015 ms, mem = 72224 KiB, score = 0
 测试数据 #6: TimeLimitExceeded, time = 1015 ms, mem = 72224 KiB, score = 0
 TimeLimitExceeded, time = 6356 ms, mem = 72224 KiB, score = 45
 还没-1多
- 
  0@ 2014-06-10 17:20:49我就把cincout改成printfscanf就过了!!!!!!天哪!!!!! 
 用cincout时:
 测试数据 #0: Accepted, time = 31 ms, mem = 7144 KiB, score = 0
 测试数据 #1: Accepted, time = 46 ms, mem = 7148 KiB, score = 10
 测试数据 #2: Accepted, time = 46 ms, mem = 7148 KiB, score = 15
 测试数据 #3: Accepted, time = 296 ms, mem = 7148 KiB, score = 15
 测试数据 #4: TimeLimitExceeded, time = 1107 ms, mem = 7144 KiB, score = 0
 测试数据 #5: Accepted, time = 1809 ms, mem = 7148 KiB, score = 25
 测试数据 #6: TimeLimitExceeded, time = 1060 ms, mem = 7148 KiB, score = 0
 改成printfscanf后:
 测试数据 #0: Accepted, time = 0 ms, mem = 7148 KiB, score = 0
 测试数据 #1: Accepted, time = 7 ms, mem = 7148 KiB, score = 10
 测试数据 #2: Accepted, time = 0 ms, mem = 7144 KiB, score = 15
 测试数据 #3: Accepted, time = 15 ms, mem = 7148 KiB, score = 15
 测试数据 #4: Accepted, time = 109 ms, mem = 7148 KiB, score = 20
 测试数据 #5: Accepted, time = 140 ms, mem = 7148 KiB, score = 25
 测试数据 #6: Accepted, time = 124 ms, mem = 7144 KiB, score = 15
 太可怕了!!!!!我和我的小伙伴都惊呆了!
- 
  0@ 2014-02-25 22:57:29我和我的小伙伴都惊呆了!我竟然不知道有负环,0分和100分的差距让我接受不了。。。 
- 
  0@ 2013-10-23 13:09:25测试数据 #0: Accepted, time = 0 ms, mem = 6328 KiB, score = 0 
 测试数据 #1: Accepted, time = 15 ms, mem = 6332 KiB, score = 10
 测试数据 #2: Accepted, time = 15 ms, mem = 6328 KiB, score = 15
 测试数据 #3: Accepted, time = 140 ms, mem = 6328 KiB, score = 15
 测试数据 #4: Accepted, time = 968 ms, mem = 6328 KiB, score = 20
 测试数据 #5: Accepted, time = 406 ms, mem = 6328 KiB, score = 25
 测试数据 #6: Accepted, time = 62 ms, mem = 6332 KiB, score = 15
 Accepted, time = 1606 ms, mem = 6332 KiB, score = 100
 第四个点= = .... 吓死爹了。
- 
  0@ 2013-02-16 10:17:22
- 
  0@ 2012-10-26 21:54:27├ 测试数据 01:答案正确... (0ms, 12492KB) 
 ├ 测试数据 02:答案正确... (0ms, 12492KB)
 ├ 测试数据 03:答案正确... (0ms, 12492KB)
 ├ 测试数据 04:答案正确... (0ms, 12492KB)
 ├ 测试数据 05:答案正确... (0ms, 12492KB)
 ├ 测试数据 06:答案正确... (0ms, 12492KB)
 ├ 测试数据 07:答案正确... (0ms, 12492KB)终于ac了。。。这套题各种第七个点wa。。。我也不知道为什么,把整道题重新写了一遍居然就ac了,真是神奇。 
 这道题判断负环我用的是dist,如果有负环那么这个负环一定和start相连。
- 
  0@ 2012-10-15 20:12:42├ 测试数据 01:答案正确... (0ms, 24264KB) 
 ├ 测试数据 02:答案正确... (0ms, 24264KB)
 ├ 测试数据 03:答案正确... (0ms, 24264KB)
 ├ 测试数据 04:答案正确... (0ms, 24264KB)
 ├ 测试数据 05:答案正确... (0ms, 24264KB)
 ├ 测试数据 06:答案正确... (0ms, 24264KB)
 ├ 测试数据 07:答案正确... (0ms, 24264KB)
 ___|\__|\__|\__|\__|\__|\__|\__|\__|\__|\__|\__|\__|\__|\__|
 好吧,用的空间大了些。。。。
 还有一个比较猥琐的办法判断负环,当spfa的栈接近于爆时,便有负环。。。空间就开大点吧,两次spfa,一次对于随机的一个点判断负环,一次对于s做,AC。
 顺求各位大神笼罩,保我noip。ORZ
- 
  0@ 2012-09-06 09:54:03我终于知道这道题为啥这么低Ac率了.. 
 是因为有这么一群英雄好汉勇于向P1053发起攻击,倒了然后站起来继续攻打~~
 有的人胜利了,就在这里发题解,引人传唱,永垂不朽
 有的人遍体鳞伤后决定放弃,于是在这里留下名字作为纪念
 更有的人还踌躇满志地誓要搞掂这道题,~!!!!
- 
  0@ 2012-08-09 15:44:53spfa+判断、、 
 交了4次。。
 陷阱确实多,
 1.s不一定在负权回路里,所以如果直接对s做spfa,会错。
 2.两点之间居然有可能有多条边。。。读数据的时候,不要一味的覆盖,要保留两点之间最小值的边。我的做法就是对每个点都进行spfa,这样判断负环回路大家都会的,看入队次数是否大于n。但是单纯这样会tle,所以做如下优化(ps:我没做到0ms,但是,可以过了,希望大牛帮忙继续优化) 
 优化
 1.在枚举每个顶点进行SPFA时,可以判断某个顶点之前枚举时是否入过队列,如果有入过的话,则代表这个顶点有无负权回路已经被计算过,可以不再计算。
 2.在枚举的过程中,当这个顶点的最短路(d)