/*
又是一道差分約束的題目。。。一樣的,又被卡了好久 - -。
題目意思很好懂。
這個差分約束用spfa的主要就是spfa要用stack實現而不能用queue來實現。
這個就體現出stack實現的快速優勢。
用queue會光榮的交上一次tle
可以用stl裏的stack,也可自己寫,自己寫的要比stl的快的多。
我在下面都給出了,應該是自己寫的stack要比stl的stack要快200ms左右,還是很可觀的。
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<stack>
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 30010;
int n,m;
typedef struct
{
int to;
int next;
int w;
} Node;
Node edge[N*5];
int dis[N];
int vis[N];
int head[N];
int inqueue[N];
int num_edge;
void addedge(int a,int b,int w)
{
edge[num_edge].to = b;
edge[num_edge].w = w;
edge[num_edge].next = head[a];
head[a] = num_edge++;
}
/****************************************************************************************/
bool spfa(int start)/*stl stack 實現*/
{
memset(vis,false,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
stack<int>s;
s.push(start);
vis[start] = true;
dis[start] = 0;
inqueue[start]++;
while(!s.empty())
{
int cur = s.top();
s.pop();
for(int i = head[cur] ; i != -1 ; i = edge[i].next)
{
int x = edge[i].to;
if(dis[x] > dis[cur] + edge[i].w )
{
dis[x] = dis[cur] + edge[i].w;
if(!vis[x])
{
s.push(x);
vis[x] = true;
inqueue[x]++;
if(inqueue[x] > n)
{
return false;
}
}
}
}
vis[cur] = false;
}
return true;
}
/*******************************************************************************************/
/*******************************************************************************************/
int s[N];/*數組模擬stack 實現,效率比stl要快*/
bool spfa(int start)
{
int top;
memset(dis,0x3f,sizeof(dis));
memset(vis,false,sizeof(vis));
dis[start] = 0;
s[0] = start;
top = 1;
vis[start] = true;
while(top)
{
int cur = s[--top];
for(int i = head[cur] ; i != -1 ; i = edge[i].next)
{
int x = edge[i].to;
if(dis[x] > dis[cur] + edge[i].w)
{
dis[x] = dis[cur] + edge[i].w;
if(!vis[x])
{
s[top++] = x;
vis[x] = true;
}
}
}
vis[cur] = false;
}
return true;
}
/**********************************************************************************************************/
int main()
{
while(scanf("%d %d",&n,&m) != EOF)
{
memset(head,-1,sizeof(head));
int a,b,w;
num_edge = 0;
for(int i = 0 ; i < m ; i++)
{
scanf("%d %d %d",&a,&b,&w);
addedge(a,b,w);
}
spfa(1);
cout<<dis[n]<<endl;
}
return 0;
}
poj 3159 Candies(差分約束 spfa stack實現)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.