http://acm.hdu.edu.cn/showproblem.php?pid=4318
求最短路水题
用spfa 过了,标称用的堆来做的,也是3000+msAC的样子
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int INF=0x3f3f3f3f; const int V=50010; //顶点 const int E=V*100; //边 int pnt[E],nxt[E]; double cost[E]; int e,head[V]; int que[E]; bool vis[V]; double dist[V]; void addedge(int u,int v,double c) { pnt[e]=v,cost[e]=c,nxt[e]=head[u],head[u]=e++; } double spfa(int src,int sink,int n,double tot) { for(int i=1;i<=n;i++) vis[i]=0,dist[i]=0; dist[src]=tot; int l=0,r=1; que[0]=src; vis[src]=1; while(l<r) { int u,v; u=que[l++]; //cout<<u<<" "<<dist[u]<<endl; vis[u]=false; for(int i=head[u];i!=-1;i=nxt[i]) { v=pnt[i]; //cout<<v<<" "<<cost[i]<<endl; if(dist[v]<dist[u]*cost[i]) { dist[v]=dist[u]*cost[i]; if(!vis[v]&&dist[v]>0) que[r++]=v,vis[v]=1; } } } return dist[sink]; } int main() { int n,m,a,b,src,sink; double c,tot; while(scanf("%d",&n)==1) //边的标号为 1 - n { e=0; memset(head,-1,sizeof(head)); for(int i=0;i<n;i++) { scanf("%d",&m); for(int j=0;j<m;j++) { scanf("%d%lf",&a,&c); addedge(i+1,a,(100-c)*1.0/100.0); // addedge(a,i+1,(100-c)*1.0/100.0); } } scanf("%d%d%lf",&src,&sink,&tot); //TODO spfa(1,n) double ans=spfa(src,sink,n,tot); if(ans<=0) printf("IMPOSSIBLE!\n"); else printf("%.2lf\n",tot-ans); } return 0; }