http://acm.hdu.edu.cn/showproblem.php?pid=2066
老早以前做的题 翻出来重新刷了次复习下dijkstra
思路:
加一个起始点 把相邻的城市与起始点相连 距离为零
这样就可以把多源化成单源
#include "stdio.h"
#include "string.h"
const int maxn = 1005;
const int inf = 1000000;
int map[maxn][maxn];
int max_city;
bool vis[maxn];
int dis[maxn];
void dijkstra(int x)
{
memset( vis,0,sizeof(vis) );
for( int i = 0; i <= max_city; i ++ )
dis[i] = map[x][i];
dis[x] = 0;
for( int i = 1; i <= max_city; i ++ )
{
int temp = inf; int p = x;
for( int j = 1; j <= max_city; j ++ )
{
if( !vis[j] && dis[j] < temp )
temp = dis[p=j];
}
vis[p] = true;
for( int j = 0; j <= max_city; j ++ )
{
if( map[p][j] != inf && dis[j] > dis[p] + map[p][j] )
dis[j] = dis[p] + map[p][j];
}
}
}
int main()
{
int t,s,d,a,b,c,temp;
while( scanf("%d%d%d",&t,&s,&d) == 3 )
{
for( int i = 0; i < maxn; i ++ )
{
for( int j = 0; j < maxn; j ++ )
if( i == j )
map[i][j] = 0;
else
map[i][j] = map[j][i] = inf;
}
max_city = 0;
for( int i = 0; i < t; i ++ )
{
scanf("%d%d%d",&a,&b,&c);
if( map[a][b] > c )
map[a][b] = map[b][a] = c;
max_city = ( a>b ? a:b) > max_city ? (a>b?a:b) : max_city;
}
for( int i = 0; i < s; i ++ )
{
scanf("%d",&temp);
map[0][temp] = map[temp][0] = 0;
}
dijkstra(0);
int min = inf;
for( int i = 0; i < d; i ++ )
{
scanf("%d",&temp);
if( min > dis[temp] )
min = dis[temp];
}
printf("%d\n",min);
}
return 0;
}
优先队列版
#include "stdio.h"
#include "string.h"
#include "queue"
using namespace std;
const int maxn = 1005;
const int inf = 1<<30;
int map[maxn][maxn];
int max_city;
bool vis[maxn];
int dis[maxn];
typedef pair<int,int>pii;//捆绑
void dijkstra(int x)
{
priority_queue<pii,vector<pii>,greater<pii> >que; //优先队列
memset( vis,0,sizeof(vis) );
dis[x] = 0;
que.push( make_pair( dis[x],x ) );
while( !que.empty() )
{
pii u = que.top(); que.pop();
int v = u.second;
if( vis[v] )
continue;
vis[v] = true;
for( int j = 1; j <= max_city; j ++ )
{
if( map[v][j] != inf && dis[j] > dis[v] + map[v][j] )
{
dis[j] = dis[v] + map[v][j];
que.push( make_pair(dis[j],j) );
}
}
}
}
int main()
{
int t,s,d,a,b,c,temp;
while( scanf("%d%d%d",&t,&s,&d) == 3 )
{
for( int i = 0; i < maxn; i ++ )
{
for( int j = 0; j < maxn; j ++ )
if( i == j )
map[i][j] = 0;
else
map[i][j] = map[j][i] = inf;
}
max_city = 0;
for( int i = 0; i < t; i ++ )
{
scanf("%d%d%d",&a,&b,&c);
if( map[a][b] > c )
map[a][b] = map[b][a] = c;
max_city = ( a>b ? a:b) > max_city ? (a>b?a:b) : max_city;
}
for( int i = 0; i <= max_city; i ++ ) //注意 要先初始化话dis数组 不然相邻的城市的dis会变成0 不会更新
dis[i] = map[0][i];
for( int i = 0; i < s; i ++ )
{
scanf("%d",&temp);
map[0][temp] = map[temp][0] = 0;
}
dijkstra(0);
int min = inf;
for( int i = 0; i < d; i ++ )
{
scanf("%d",&temp);
if( min > dis[temp] )
min = dis[temp];
}
printf("%d\n",min);
}
return 0;
}
FLoyd 优化
#include "stdio.h"
#include "string.h"
const int inf = 1000000;
int map[1115][1115];
int max_city;
bool mark1[1005],mark2[1005];
int Floyd()
{
int temp=inf;
for( int k=1;k<=max_city;k++ )
{
for( int i=1;i<=max_city;i++ )
{
if( map[i][k]!=inf )
for( int j=1;j<=max_city;j++ )
{
if( map[i][j] > map[i][k] + map[k][j] )
{
map[i][j] = map[i][k] + map[k][j];
}
if( mark1[i] && mark2[j] )
temp=temp<map[i][j]?temp:map[i][j];
}
}
}
return temp;
}
int main()
{
int t,s,d,a,b,c,i,j,temp;
while( scanf("%d%d%d",&t,&s,&d)==3 )
{
for( i=0;i<1005;i++ )
for( j=i+1;j<=1005;j++ )
map[i][j]= map[j][i] = inf;
max_city=0;
for( i=0;i<t;i++ )
{
scanf("%d%d%d",&a,&b,&c);
if( map[a][b]>c )
map[a][b]=map[b][a]=c;
max_city=(a>b ? a:b) > max_city ? (a>b?a:b) : max_city;
}
memset(mark1,0,sizeof(mark1));
memset(mark2,0,sizeof(mark2));
for( i=0;i<s;i++ )
{
scanf("%d",&temp);
mark1[temp]=true;
}
for( i=0;i<d;i++ )
{
scanf("%d",&temp);
mark2[temp]=true;
}
printf("%d\n",Floyd());
}
return 0;
}