Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 17673 | Accepted: 4717 |
Description
Input
Output
Sample Input
1 4
10000 3 2
2 8000
3 5000
1000 2 1
4 200
3000 2 1
4 200
50 2 0
Sample Output
5250
解题思路:
dijkstra+枚举:在[l[1]-M, l[1]], [ l[1]-M+1, l[1]+1]....[l[1], l[1]+M]之间枚举最短路径。
注意是有向图,MD wa了一下午。郁闷啊
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define MAX_VALUE 1e8
using namespace std;
int dijkstra(int g[101][101], int* l,int N,int M, bool can[101])
{
int d[101];
bool s[101];
for(int i=0;i<=N;i++)
{
d[i]=MAX_VALUE;
}
memset(s,0,sizeof(s));
d[0]=0;
l[0]=l[1];
int minNode;
int minValue;
for(int i=1; i<=N; i++)
{
//find minNode
minValue=MAX_VALUE;
minNode=0;
for(int j=0; j<=N; j++)
{
if(s[j]==false && d[j]<minValue && can[j])
{
minValue=d[j];
minNode=j;
}
}
s[minNode]=true;
//relax
for(int j=1; j<=N; j++)
{
if( g[minNode][j]!=MAX_VALUE && d[j]>g[minNode][j]+d[minNode]&& can[j])
{
d[j]=g[minNode][j]+d[minNode];
}
}
}
return d[1];
}
int main()
{
int M,N; //numbers of nodes, [1,100]
int P,L,X;
int T,V;
int g[101][101];
int l[101];
bool can[101];
int rlt;
int minrlt;
while(scanf("%d%d",&M,&N)!=EOF)
{
for(int i=0;i<=N;i++)
{
for(int j=0;j<=N;j++)
g[i][j]=MAX_VALUE;
}
for(int i=1; i<=N; i++)
{
scanf("%d%d%d",&P,&L,&X);
g[0][i]=P;
l[i]=L;
for(int j=1; j<=X; j++)
{
scanf("%d%d",&T,&V);
g[T][i]=V;
}
}
//dijkstra
rlt=MAX_VALUE;
minrlt=MAX_VALUE;
for(int i=0; i<=M; i++)
{
memset(can,0,sizeof(can));
for(int j=0; j<=N;j++)
{
if( l[j] >= l[1]-M+i && l[j]<=l[1]+i)
can[j]=true;
}
rlt=dijkstra(g,l,N,M,can);
if(rlt<minrlt)
minrlt=rlt;
}
printf("%d\n",minrlt);
}
return 0;
}