题解 P2384 【最短路】

斯德哥尔摩

2017-09-29 11:14:00

Solution

这是一道裸的 SPFA ,然而我交了 10+ 次才过。。。 注: memset 有毒。。。不到万不得已不要用。。。 附代码: ```cpp #include<iostream> #include<algorithm> #include<cstdio> #include<queue>//队列头文件 #include<cstring> #define MOD 9987 #define MAXN 1010 #define MAXM 10000010 #define MAX 99999999//最大值 using namespace std; int n,m,c=1,head[MAXN]; long long path[MAXN];//一定要开 long long,不然会炸。。。 bool vis[MAXN]; struct node{//边 int next,to,w; }a[MAXM]; inline int read(){//弱弱的读入优化。。。 int date=0,w=1;char c=0; while(c!='-'&&(c<'0'||c>'9')){if(c=='-')w=-1;c=getchar();} while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();} return date*w; } inline int relax(int u,int v,int w){//松弛操作 if(path[v]>(long long)path[u]*w){ path[v]=(path[u]*w);//乘积,不 mod 其实也行 return 1; } return 0; } void add(int u,int v,int w){//加边操作 a[c].to=v;a[c].w=w; a[c].next=head[u]; head[u]=c++; a[c].to=u;a[c].w=w; a[c].next=head[v]; head[v]=c++; } void spfa(){//开始工(gao)作(shi) int u,v; queue<int> q;//队列 q.push(1); path[1]=1;//一定要设为1,因为是乘积 vis[1]=true; while(!q.empty()){ u=q.front();//取队首 q.pop();//弹出 vis[u]=false; for(int i=head[u];i;i=a[i].next){ v=a[i].to; if(relax(u,v,a[i].w)&&!vis[v]){//松弛 vis[v]=true; q.push(v);//松弛成功则入队 } } } printf("%lld\n",path[n]%MOD);//输出 } int main(){ int u,v,w; memset(vis,false,sizeof(vis)); n=read();m=read(); for(int i=1;i<=n;i++)path[i]=MAX;//本来用的是 memset ,结果永久 WA 了一个点 for(int i=1;i<=m;i++){ u=read();v=read();w=read(); add(u,v,w);//加边 } spfa();//调用 return 0; ``` }//完美的结束。。。