MDeath-Kid

- M I T & Y
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

hdu 2112

Posted on 2011-04-21 12:42  MDeath-Kid  阅读(347)  评论(0编辑  收藏  举报
/*一开始TLE的代码,写个hashf函数*/
#include<iostream>
#include<string.h>
#include<limits.h>
#include<stdio.h>
#include<vector>

#define MAXN 1005
#define INTMAX 1000000

using namespace std;
vector<string> strTmp;
int hashnum=0;
int map[MAXN][MAXN],minl[MAXN],pre[MAXN];
int hashf(string temp)
{
    for(unsigned int i = 0;i<strTmp.size();i++)
        if(temp==strTmp[i])
            return i;
    strTmp.push_back(temp);
    return hashnum++;
}
int dijkstra(int a,int b)
{
    int n = hashnum,i,j,k;
    int v[MAXN] = {0};
    for(minl[a]=0,i = 0;i<n;i++)
    {
        for(k=-1,j=0;j<n;j++)
            if(!v[j]&&(k==-1||minl[j]<minl[k]))
                k=j;
        for(v[k]=1,j=0;j<n;j++){
            if(!v[j]&&minl[k]+map[k][j]<minl[j])
                minl[j]=minl[k]+map[k][j];}
    }
    if(minl[b]==MAXN) return -1;
    else return minl[b];
}
int main()
{
    //freopen("d:\\1.txt","r",stdin);
    int N;
    string a,b;
    while(cin>>N&&(N!=-1))
    {
        memset(map,INTMAX,sizeof(map));
        memset(minl,INTMAX,sizeof(minl));
        memset(pre,0,sizeof(pre));
        string from,goal;
        cin>>from>>goal;
        for(int i = 0,v;i<N;i++){
            cin>>a>>b>>v;
            map[hashf(a)][hashf(b)] = map[hashf(b)][hashf(a)] = v;
            map[hashf(a)][hashf(a)] = map[hashf(b)][hashf(b)] = 0;
        }//,if(v<map[hashf(a)][hashf(b)])cout<<map[hashf(b)][hashf(a)]<<endl;
        cout<<dijkstra(hashf(from),hashf(goal))<<endl;
    }
}
/*ACMer:MDK
2011-04-21 12:15:00 Accepted 2112 843MS 380K 1892 B G++ MDK
*/
#include
<iostream>
#include
<string.h>
#include
<stdio.h>
#include
<vector>
#include
<limits.h>
#define MAXN 160
const int INTMAX=0xfffffff;

using namespace std;
//vector<string> strTmp;
char strTmp[160][35];
int hashnum=0;
int mat[MAXN][MAXN],minl[MAXN],pre[MAXN];
int hashf(char temp[])
{
for(int i = 0;i<hashnum;i++)
if(strcmp(temp,strTmp[i])==0)
return i;
strcpy(strTmp[hashnum],temp);
return hashnum++;
}

int dijkstra(int a,int b)
{
int n = hashnum,i,j,k;
int v[MAXN] = {0};
for(minl[a]=0,i = 0;i<n;i++)
{
for(k=-1,j=0;j<n;j++)
if(!v[j]&&(k==-1||minl[j]<minl[k]))
k
=j;
for(v[k]=1,j=0;j<n;j++){//cout<<minl[j]<<endl;
if(!v[j]&&(minl[k]+mat[k][j])<minl[j])
minl[j]
=minl[k]+mat[k][j];}
}
if(minl[b]>=MAXN) return -1;
else return minl[b];
}
int main()
{
freopen(
"d:\\1.txt","r",stdin);
int N;
char a[35],b[35];
while(scanf("%d",&N),N!=-1)
{
for(int i = 0;i<MAXN;i++)
for(int j = 0;j<MAXN;j++)
mat[i][j]
= INTMAX;
for(int i = 0;i<MAXN;i++)
minl[i]
=INTMAX;
memset(pre,
0,sizeof(pre));
memset(strTmp,
'\0',sizeof(strTmp));
hashnum
= 0;
char from[35],goal[35];
scanf(
"%s %s",from,goal);
for(int i = 0,v;i<N;i++){
int x,y;
scanf(
"%s %s %d",a,b,&v);
x
=hashf(a);
y
=hashf(b);
if(v<mat[x][y])
mat[x][y]
= mat[y][x] = v;
if(x==y)
mat[x][y]
= mat[y][x] = 0;
}
int x=hashf(from),y = hashf(goal);
if(N==0)
printf(
"-1\n");
else if(x==y)
printf(
"0\n");
else
printf(
"%d\n",dijkstra(x,y));

}
}

主要方法:hash+dijkstra;

在这个代码WA的那段时间里面,我怀疑了很多很多的东西,包括dijkstra,hash,甚至是数组的赋值,还是自己不坚定,多A,就有扎实的基础了!

这个题真是让我非常之纠结,昨晚一直在调试,3个小时没找到毛病,一开始用vector和string做,cin对数据量大的超时了,最困惑的是hashnum没清零,弄的老是RE,后来就该啊该,改啊改,改了全部茫然了,终于用char没超时,WA了,就在想,什么情况没考虑到?什么地方没做好,我都愁的不行,最后发现memset函数用错了,哭T_T

memset(map,INTMAX,sizeof(map));
memset(minl,INTMAX,sizeof(minl));
这种根本做不到对map和minl的清零,可以使memset(map,127,sizeof(map));

因为memset是以字节为单位就是对array指向的内存的4个字节进行赋值,每个都用ASCII为1的字符去填充,转为二进制后,127就是01111111,占一个字节。一个INT元素是4字节,合一起就是01111111011111110111111101111111,就等于2139062143,就完成了对一个INT元素的赋值了,虽然这个复制并不是INT_MAX。

字节运算,很好很强大!