/*一开始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。
字节运算,很好很强大!