Description
Input
Output
Sample Input
1 2 1
1 4 3
2 3 1
2 5 2
4 6 2
5 3 2
0
0
0
1 3
0
2 3 5
Sample Output
HINT
對於 20%的數據,滿足 N≤15,M≤50;
對於 50%的數據,滿足 N≤500,M≤6,000;
對於 100%的數據,滿足 N≤3,000,M≤70,000,1≤wi≤108
。
輸入數據保證一定有解,且不會存在維持某個城市結界的結界發生器在這個
城市內部。
連接兩個城市的道路可能不止一條, 也可能存在一個城市自己到自己的道路。
分析:dijkstra+限制。
因爲是單源點,所以很容易想到dijkstra,至於爲什麼不用SPFA,這和dijkstra的特點有關。
到一個點是有兩個時間的,一個是真實距離,一個是破壞掉所有防禦的時間,取較大值。
代碼如下:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int N,M;
int map[3050][3050],dis1[3050],num[3050],dis2[3050];
bool vis[3050],a[3050][3050];
void init()
{
memset(map,100,sizeof(map));
memset(a,true,sizeof(a));
int x,y,z;
scanf("%d%d",&N,&M);
for(int i=1;i<=M;i++)
{
scanf("%d%d%d",&x,&y,&z);
if(map[x][y]>z) map[x][y]=z;
}
for(int i=1;i<=N;i++)
{
scanf("%d",&num[i]);
for(int j=1;j<=num[i];j++)
{
scanf("%d",&x);
a[x][i]=false;
}
}
}
void dijkstra()
{
memset(dis1,100,sizeof(dis1));
memset(vis,false,sizeof(vis));
memset(dis2,0,sizeof(dis2));
dis1[1]=0;
for(int i=1;i<=N;i++)
{
int minn=1684300900,p=0;
for(int j=1;j<=N;j++)
if(!vis[j]&&!num[j]&&max(dis1[j],dis2[j])<minn)
{
minn=max(dis1[j],dis2[j]);
p=j;
}
if(p==0) break;
vis[p]=true;
for(int j=1;j<=N;j++)
if(!vis[j])
{
if(!a[p][j])
{
num[j]--;
dis2[j]=max(dis2[j],minn);
}
if(minn+map[p][j]<dis1[j]) dis1[j]=minn+map[p][j];
}
}
if(!num[N]) printf("%d\n",max(dis1[N],dis2[N]));
else printf("-1\n");
}
int main()
{
init();
dijkstra();
return 0;
}