【Dijkstra算法的思想】//设dis[x]为源点s到顶点x的最短距离
// adj[x][y]为顶点x、y之间的距离
dis[y]=min(dis[y],dis[x]+adj[x][y]);
【时空复杂度】SP_Dijkstra(G, s) //求单源s到其它点的最短距离
for i=1 to n do
dis[i] ← ∞ //初始化每点到s距离
inA[i] ← false //设顶点不在A中
dis[s] ← 0 //将dis[s]设为0,准备取出
for i=1 to n do
v ← get-min() //取dis[?]中最小的值c和顶点v,
inA[ v ] ← true //v放入A中
updata( v ) //检查(v,B),松弛dis[? ]
【题意分析】Bessie喜欢为在外面的奶牛做晚餐,Bessie按响铃给他们一个信号叫他们进来就可以了。
晚餐将在T (1 <= T <= 1,000,000)毫秒完成,而且Bessie强调那些想吃她晚餐的奶牛必须准时到。
这些牛在F (1 <= F <= 500)各不同的草地标号为1~F用P(1 <= P <= 10,000)个双向的小路连接。Bessie在第1个草地, 给出一头牛走每一条小路所用的时间,问多少个草地上的奶牛可以在T毫秒内到Bessie 所在的草地,假设多头牛可以共享一条路。
PROBLEM NAME: cooking
INPUT FORMAT:
第一行:三个整数用空格隔开,T,F,P
第2~P+1 行,每行表示在两个草地间的一条路,给出三个用空格隔开的整数,分别表示,
这条路所连接的一个草地和另一个草地以及奶牛走这条路所需要的毫秒数(1..1,000,000)
SAMPLE INPUT (file cooking.in):
1000 5 6
1 2 300
2 4 200
3 4 600
3 4 800
5 3 100
2 5 650
INPUT DETAILS:
晚餐将在1000毫秒完成,有5块草地,用6条小路连接
OUTPUT FORMAT:
一行,可以在T毫秒内到达Bessie所在的位置草地的个数
SAMPLE OUTPUT (file cooking.out):
4
OUTPUT DETAILS:
在1,2,4,5号草地的奶牛可以在1000毫秒内到达Bessie所在的草地,而3号草地上的奶牛不可以
#include<cstdio>
#define min(x,y) (x<y?x:y)
const int SIZE=500+5;
const int oo=0x7ffffff;
int T,F,P,G[SIZE][SIZE],dis[SIZE];
bool visited[SIZE];
int get_min();
void update(int);
int main() {
freopen("cooking.in","r",stdin);
freopen("cooking.out","w",stdout);
scanf("%d%d%d",&T,&F,&P);
for(int i=0; i!=F+1; ++i)
for(int j=0; j!=F+1; ++j)
G[i][j]=oo;
for(int i=0; i!=P; ++i) {
int x,y,distance;
scanf("%d%d%d",&x,&y,&distance);
G[x][y]=min(G[x][y],distance);
G[y][x]=min(G[y][x],distance);
}
for(int i=0; i!=F+1; ++i) {
dis[i]=oo;
visited[i]=false;
}
dis[1]=0;
for(int i=0; i!=F+1; ++i) {
int v=get_min();
visited[v]=true;
update(v);
}
int ans=1;
for(int i=2;i!=F+1;++i)ans+=dis[i]<=T;
printf("%d\n",ans);
return 0;
}
int get_min() {
int minV=0;
for(int i=1; i!=F+1; ++i)
if(!visited[i])minV=dis[i]<dis[minV]?i:minV;
return minV;
}
void update(int v) {
for(int i=1; i!=F+1; ++i)
for(int j=1; j!=F+1; ++j)
dis[j]=min(dis[j],dis[i]+G[i][j]);
}