您的位置:首页 > 其它

一个人的旅行 HDU 2066 &&HDU Today HDU 2112

2013-08-06 14:22 288 查看
一个人的旅行 HDU 2066

迪杰斯特拉:Dijkstra:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
using namespace std;
int inf=1000000;//以后如果结果输出的是(负数或很大的整数),可能是(这个开大了或开小了)
int a[1005][1005],w[1005];
int main()
{
int t,s,d,n,i,j,p,min1,a1,a2,a3;
while(scanf("%d%d%d",&t,&s,&d)!=EOF)
{
memset(a,inf,sizeof(a));
n=0;
while(t--)
{
scanf("%d%d%d",&a1,&a2,&a3);
if(a[a1][a2]>a3)
{
a[a1][a2]=a3;
a[a2][a1]=a3;
}
if(a1>n) n=a1;
if(a2>n) n=a2;
}
n++;
for(i=1;i<=n;i++)
a[i][i]=0;
while(s--)
{
scanf("%d",&a1);
a[0][a1]=0;
}
while(d--)
{
scanf("%d",&a1);
a[a1]
=0;
}
memset(w,0,sizeof(w));
for(i=1;i<=n;i++)
{
min1=inf;
for(j=1;j<=n;j++)
if(!w[j]&&min1>a[0][j])
{
p=j;
min1=a[0][j];
}
w[p]=1;
for(j=1;j<=n;j++)
if(!w[j]&&a[0][j]>a[0][p]+a[p][j])
{
a[0][j]=a[0][p]+a[p][j];
a[j][0]=a[0][j];
}
}
printf("%d\n",a[0]
);
}
return 0;
}


下面讲一下这个迪杰斯特拉算法的意思:

就是以起点开始,先找到一个中间点(相比之下最小的那个),再以这个中间点作为桥梁,更新起点通过中间点到其他点的距离。以后反复循环,以前做过中间点的,就可以跳过此步骤,当里面的点全部都做过中间点或没有被赋值的(初始值为很大的一个数),就可以跳过此循环了。

这个算法的复杂度应该是n^2,比弗洛伊德算法(Floyd算法)n^3快一些!!!!

注意:(求最小径的二维数组)(每次赋值要进行俩次,因为他们是对称的!!)(还有起点与终点在同一位置的情况)

下面的这个题目要用map来转换字符串!!(第一次见到用map)思考!!!!!!!!!

HDU Today HDU 2112

就是难点在map:

可以用Floyd或Dijkstra:

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<map>
#include<string.h>
#include<string>
using namespace std;
int a[155][155];
char a3[35],b[35],a1[35],a2[35];
map<string,int> q;
int main()
{
int n,i,j,m,d,k;
while(scanf("%d",&n)!=EOF)
{
if(n==-1)
break;
if(n==0)
{
printf("-1\n");
continue;
}
q.clear();
memset(a,10000,sizeof(a));
scanf("%s%s",a3,b);
q[a3]=1;//因为起点和终点可以一样的!
q=2;//同上
m=2;
while(n--)
{
scanf("%s%s%d",a1,a2,&d);
if(!q[a1])
q[a1]=++m;
if(!q[a2])
q[a2]=++m;
if(a[q[a1]][q[a2]]>d)
{
a[q[a1]][q[a2]]=d;
a[q[a2]][q[a1]]=d;
}
}
for(i=1;i<=m;i++)
a[i][i]=0;
for(k=1;k<=m;k++)
for(i=1;i<=m;i++)
for(j=i+1;j<=m;j++)
{
if(a[i][j]>a[i][k]+a[k][j])
{
a[i][j]=a[i][k]+a[k][j];
a[j][i]=a[i][j];
}
}
if(a[q[a3]][q[b]]<10000)
printf("%d\n",a[q[a3]][q[b]]);         else
printf("-1\n");
}
return 0;
}


那么接下用[b]Dijkstra
意义也不大

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<map>
#include<string.h>
#include<string>
using namespace std;
int a[155][155],w[155];
char a3[35],b[35],a1[35],a2[35];
map<string,int> q;
int main()
{
int n,i,j,m,d,p,min1;
while(scanf("%d",&n)!=EOF)
{
if(n==-1)
break;
if(n==0)
{
printf("-1\n");
continue;
}
q.clear();
memset(a,10000,sizeof(a));
scanf("%s%s",a3,b);
q[a3]=1;
q=2;
m=2;
while(n--)
{
scanf("%s%s%d",a1,a2,&d);
if(!q[a1])
q[a1]=++m;
if(!q[a2])
q[a2]=++m;
if(a[q[a1]][q[a2]]>d)
{
a[q[a1]][q[a2]]=d;
a[q[a2]][q[a1]]=d;
}
}
for(i=1;i<=m;i++)
a[i][i]=0;
memset(w,0,sizeof(w));
for(i=1;i<=m;i++)
{
min1=10000;
for(j=1;j<=m;j++)
if(!w[j]&&min1>a[1][j])
{
p=j;
min1=a[1][j];
}
w[p]=1;
for(j=1;j<=m;j++)
if(!w[j]&&a[1][j]>a[1][p]+a[p][j])
{
a[1][j]=a[1][p]+a[p][j];
a[j][1]=a[1][j];
}
}
if(a[q[a3]][q[b]]<10000)
printf("%d\n",a[q[a3]][q[b]]);
else
printf("-1\n");
}
return 0;
}


for(i=0,h=0;i<m;i++)
{
c[i]=a1[i]+b1[i]+h;
h=c[i]/10;
c[i]=c[i]%10;
}

[b]for(i=0;i<m;i++)
{
h=a1[i]+b1[i];
c[i]=c[i]+h%10;//这个地方可能为10啊!!!!!!!!!!!!!!!!!!(严谨啊大哥。。。)
c[i+1]=c[i+1]+h/10;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: