最短路 Power transmission 用的邻表 spfa
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4318
题目大意:讲的是西电东送。让你输入N代表N个点,然后再输入M代表可以到M个地方去,每个M钟有一个表示节点,一个表示耗电的百分比,。最后输入三个数,一个是起点,一个是重点,一个是总电量。然后算出最后到达终点使得总电量最大可以是多少,不能到达的话输出IMPOSSIBLE!
这道题也就转化成了求最大的转化率。相当于最长路的计算。由于N<=50000数目比较大,所以估计邻接矩阵会超事,然后写了个邻接表的
代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> #define maxn 0x7fffffff #define N 50050 int q[N],f,r; double dis[N]; struct node { int v,p; struct node *next; }; struct head { struct node *next; }mem[N]; void insert(int u,int v,int p) { struct node *q; q = (struct node *)malloc(sizeof(struct node)); q->p = p; q->v = v; q->next = mem[u].next; mem[u].next = q; return; } void inint(int n) { int i; for(i = 1;i <= n;i++) mem[i].next = NULL; return; } void spfa(int s,int n) { int i,vis[N] = {0}; f = r = 0; q[r] = s; vis[s] = 1; for(i = 1;i <= n;i++) dis[i] = -1;//因为是求最大,所以只要是表示其最小就可以了。以为一开始基本上都大于零,所以直接赋值-1; dis[s] = 1; r++; while(f != r) { int temp; temp = q[f]; f = (f+1)%N;//让他循环起来 vis[temp] = 0; struct node *p; p = mem[temp].next; while(p) { if(dis[p->v] < dis[temp]*p->p*1.0/100.0) { dis[p->v] = dis[temp]*p->p*1.0/100.0; if(!vis[p->v]) { vis[p->v] = 1; q[r] = p->v; r = (r+1)%N; } } p = p->next; } } } int main() { int t,n,m,i,j,p; while(scanf("%d",&n)!=EOF) { inint(n); for(i = 1;i <= n;i++) { scanf("%d",&m); while(m--) { scanf("%d %d",&j,&p); insert(i,j,100-p); } } int e,s; double pow; scanf("%d %d %lf",&s,&e,&pow); spfa(s,n); if(dis[e] < 0) printf("IMPOSSIBLE!\n"); else printf("%.2lf\n",pow-dis[e]*pow); for(i = 0;i <= n;i++) mem[i].next = NULL; } }