最短路 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;
    }
}

 

posted @ 2012-08-15 20:10  某某。  阅读(202)  评论(0编辑  收藏  举报