题目:点击打开链接
代码:
<pre name="code" class="cpp">#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
#define inf 0x3f3f3f3f
#define MaxV 50010
#define MaxE 50010
typedef struct
{
int to;
int next;
double w;
} Edge;
Edge E[MaxE];
int Adj[MaxV*2];
int Size;
void Add_Edge(int u,int v,double w)
{
E[Size].to=v;
E[Size].w=w;//e数组,即起始点对应边的储存
E[Size].next=Adj[u];//next数组
Adj[u]=Size++;
return;
}
double e;
int a,b,c,d,t;
double dis[10010];
int book[10010];
int main()
{
scanf("%d",&t);
while(t--)
{
memset(dis,0,sizeof(dis));
scanf("%d%d",&a,&b);
memset( Adj,-1,sizeof( Adj));
Size=0;
for(int i=0; i<b; i++)
{
scanf("%d%d%lf",&c,&d,&e);
Add_Edge(c,d,e/100);
Add_Edge(d,c,e/100);
}
for(int i=1; i<=a; i++)
dis[i]=-inf;
for(int i=Adj[1]; i!=-1; i=E[i].next)
{
if(dis[E[i].to]>0)
dis[E[i].to]=max(dis[E[i].to],E[i].w);
else
dis[E[i].to]=E[i].w;
还有这里,有重边,要取最大的,
}
dis[1]=1.0;
memset(book,0,sizeof(book));
book[1]=1;
for(int i=1; i<=a-1; i++)
{
double minn=-inf;
这里原来我用的是int 型的,我真是太粗心太大意了,
int u=1;
for(int j=1; j<=a; j++)
{
if(book[j]==0&&dis[j]>minn)
{
minn=dis[j];
u=j;
}
}
book[u]=1;
if(u==1)
continue;
for(int j=Adj[u]; j!=-1; j=E[j].next)
{
if(dis[E[j].to]<dis[u]*E[j].w)
dis[E[j].to]=dis[u]*E[j].w;
}
// for(int i=1; i<=a; i++)
// printf("%lf ",dis[i]);
// printf("\n");
}
printf("%.6lf\n",dis[a]*100);
}
return 0;
}
提交好几回,都错了,现在已经不敢交了,以后再交。
通过这个题目,深刻感觉到,细节很重要,不仅要有思维,基本的算法代码要写对,而且细节很重要,细节决定成败。(真心有这样子的感受)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<list>
#include<cmath>
#include<vector>
#define eps 1e-6
using namespace std;
const int maxn = 100010;
struct Node{
int next,from,to;
double value;
}A[maxn];
int head[maxn<<1],node;
void init(){
node=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v,double value){
A[node].from=u;A[node].to=v;
A[node].value=value;
A[node].next=head[u];
head[u]=node++;
}
int n,m;
bool vis[maxn];
double dist[maxn];
double SPFA(int s,int t){
queue<int>Q;
memset(vis,false,sizeof(vis));
memset(dist,0,sizeof(dist));
vis[1]=true;Q.push(1);dist[1]=1;
while(!Q.empty()){
int top = Q.front();Q.pop();vis[top]=false;
for(int k = head[top];k != -1 ; k = A[k].next){
if(dist[A[k].to]<dist[top]*A[k].value){
dist[A[k].to]=dist[top]*A[k].value;
if(!vis[A[k].to]){
vis[A[k].to]=true;
Q.push(A[k].to);
}
}
}
}
return dist[n];
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
init();int a,b;
double value;
for(int i=0;i<m;++i){
scanf("%d%d%lf",&a,&b,&value);
add(a,b,value/100.0);add(b,a,value/100.0);
}
printf("%.6lf\n",SPFA(1,n)*100);
}
return 0;
}
这个是链式前向星的spfa版本,真的是我太粗心了,这个是我从小到大养成的习惯,每次代码都是打好了,然后有一些小的问题,检查不出来,真的很令人沮丧,我真的很痛恨自己这个样子,上面的那个dijistra应该是超时的,但是由于数据不强,就这样交过了,感觉如果是比赛的话,又是一遍一遍的wrong,太水了。代码这个东西,光想是办不成事的。