您的位置:首页 > 其它

hdu 1385 最短路+字典序比较 Minimum Transport Cost

2012-07-18 18:10 435 查看
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1385

题目意思很明确,这里就不讲了

从这道题的年份来看,n应该不会超过100,没有用floyd( 效率不高,不喜欢用),选择了dijkstra

注意两个点:一.起点和终点一样的情况,容易解决

二.字典序大小比较时,要把当前的点加进路径比较,discuss有个例子

4
0 2 3 9
2 0 1 5
3 1 0 3
9 5 3 1
0 0 0 0
1 4
------------
output应该是 1->2->3->4这条路径吧。以前我的是 1->3->4也a了(原话,完全引用)
当前点不加进结果就会变成1->3->4,我看别人过了,以为我的也能过,WA几次了才决定改正,可能这组数据真的被加上去了


#include<iostream>
#include<queue>
#include<cstdlib>
#include<stack>;
#define MAXN 1010
#define INF 100000001
using namespace std;
int n,m;
typedef pair<int ,int >pii;
priority_queue<pii,vector<pii>,greater<pii>   >q;
stack<int>que;
int dis[MAXN],vis[MAXN],f[MAXN],cha[MAXN];
int map[MAXN][MAXN];
void init()
{
int i;
for(i=0;i<=n;i++)
{
dis[i]=INF;
vis[i]=0;
f[i]=i;
}
}
int check(int x,int y,int k)
{
int i;
int a[110],b[110];
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
while(f[x]!=x)
{
que.push(x);
x=f[x];
}
que.push(x);
i=0;
while(!que.empty())
{
a[i++]=que.top();
que.pop();
}
a[i++]=k;//当前路径的最后一个元素
//-----------------
while(f[y]!=y)
{
que.push(y);
y=f[y];
}
que.push(y);
i=0;
while(!que.empty())
{
b[i++]=que.top();
que.pop();
}
b[i++]=k;//当前路径的最后一个元素
for(i=0;i<100;i++)
{
if(a[i]>b[i])
return 2;
else if(a[i]<b[i])
return 1;
}
return 0;
}
void dij(int x)
{
int i;
dis[x]=0;
q.push(make_pair(0,x));
while(!q.empty())
{
pii tt=q.top();
q.pop();
int v=tt.second;
if(vis[v])
continue;
vis[v]=1;
for(i=1;i<=n;i++)
{
if(vis[i]==0&&dis[i]>dis[v]+map[v][i]+cha[i])
{
dis[i]=dis[v]+map[v][i]+cha[i];
f[i]=v;
q.push(make_pair(dis[i],i));
}
else if(vis[i]==0&&dis[i]==dis[v]+map[v][i]+cha[i])//相等时进行比较
{
if(check(f[i],v,i)==2)//将i加进路径比较
f[i]=v;
}
}
}
}
int main()
{
int i,j,k,x,y,a[110],yy;
while(cin>>n,n)
{
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
cin>>map[i][j];
if(map[i][j]==-1)
map[i][j]=INF;
}
for(i=1;i<=n;i++)
cin>>cha[i];
while(cin>>x>>y,x!=-1||y!=-1)
{
yy=y;
init();
dij(x);
printf("From %d to %d :\n",x,y);
memset(a,0,sizeof(a));
while(f[y]!=y)
{
que.push(y);
y=f[y];
}
que.push(y);
i=0;
while(!que.empty())
{
a[i++]=que.top();
que.pop();
}
k=i;
printf("Path: ");
for(i=0;i<k;i++)
{
if(i==0)
printf("%d",a[i]);
else
printf("-->%d",a[i]);
}
printf("\n");
if(x==yy)//注意判断两个点相同的情况
printf("Total cost : %d\n\n",0);
else
printf("Total cost : %d\n\n",dis[yy]-cha[yy]);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: