galaxy
[Time Limit 1000MS]
[Memory Limit 65536KB]
[Description]
某陳和某Y最近對一個遊戲着迷.那是Electronic Arts今年發佈的優秀的模擬經營類遊戲,Spore.
在Spore中,玩家將經歷從單細胞生物到星系的統治者的進化過程,創造並守護你自己的文明.
而某陳在經歷了幾天*幾十分鐘/天的遊戲後,也終於已經近乎通關了.
目前,某陳統治着銀河系中標號1到N的星系,而他的帝國中心,在星系1的某顆美麗的行星之上.如同所有銀河系中的文明一樣,貿易,發展,結盟,擴張,抵抗Grox[銀河系中心的龐大的強悍的恐怖的邪惡帝國]的侵略.
某陳有足夠的力量,他的疆域蔓延幾百個光年.可是Grox異常強大,他們的飛船出現在某陳瞭解的任何地方,並時常攻擊任何位置的某陳和盟友的單位[飛船,建築,星球,甚至星系].戰爭在所難免.
某陳將從帝國中心去標號爲N的星系,他疆域的邊緣,去尋找一個可能存在的通向銀河系中心的黑洞.他要計劃一條合適的路線.
從星系g1到達g2,某陳需要花費c1的代價[主要是燃料,另外還有與沿途Grox的勢力作戰的花費],c1小於0則是因爲這樣的星系旅行,會給某陳帶來收益[來源於物流差價,以及一些殖民地的稅收..].相應地,c2則是代表從星系g2到達g1的代價.據某陳瞭解,共有M條這樣的星系間路徑.
爲了戰備,他需要選擇一條總代價最小的路線.
如此水題某陳當然懶得寫,交給你了.
[Input galaxy.in]
輸入文件包括多組數據.
對於每一組數據,第一行有2個整數n,m,如題目描述中的含義,1<=n<=1000,0<=m<=10000.
接下來的m行,每行會有四個整數g1,g2,c1,c2,如題目描述中的含義.0<=g1,g2<=n.輸入數據保證所有整數都在[-10000..10000]的範圍內.
n=0,m=0標識着輸入數據的結束.每個輸入文件包含不超過10組數據.
[Output galaxy.out]
對於每組輸入數據,輸出一行,爲從星系1到星系N的最小代價的路線的代價.
如果這樣的路線不存在,輸出'Nosuch path'.
[Sample Input]
3 2
1 2 2 -1
2 3 0 1
0 0
[Sample Output]
2
這題是簡單的單點最短路徑,但涉及到負權和環,需要用spfa來判環,還需一判斷判斷全無聯通狀態。
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<queue>
using namespace std;
const int M=1005;
int n, m;
long long d[M];
int co[M];
int vis[M];
int map[M][M];
bool flag=1;
void debug()
{
/*for (int i=1; i<=n; i++)
{
for (int j=1; j<=n; j++)
printf("%d ", map[i][j]);
printf("\n");
}*/
for (int i=1; i<=n; i++)
printf("%d ", d[i]);
printf("\n");
}
void solve()
{
flag=1;
queue <int>q;
d[1]=0;
co[1]++;
q.push(1);
vis[1]=1;
while (!q.empty())
{
int v=q.front();
//printf("%d\n", v);
q.pop();
for (int i=1; i<=n; i++)
{
if (d[v]+map[v][i]<d[i])
{
//printf("%d\n", map[v][i]);
d[i]=d[v]+map[v][i];
//printf("%d i \n", d[i]);
co[i]++;
if (co[i]>n-1)
{
flag=0;
return;
}
if (!vis[i])
{
vis[i]=1;
q.push(i);
}
}
}
vis[v]=0;
}
}
int main()
{
freopen("galaxy.in", "r", stdin);
freopen("galaxy.out", "w", stdout);
while (scanf("%d%d", &n, &m) && n!=0)
{
memset(vis, 0, sizeof(vis));
memset(co, 0, sizeof(vis));
memset(d, 127, sizeof(d));
memset(map, 127, sizeof(map));
for (int i=1; i<=m; i++)
{
int g1, g2, c1, c2;
scanf("%d%d%d%d", &g1, &g2, &c1, &c2);
map[g1][g2]=c1;
map[g2][g1]=c2;
}
solve();
//debug();
if (flag && d[n]!=2139062143) {
printf("%d\n", d[n]);
}
else printf("No such path\n");
}
return 0;
}