代码改变世界

HDU 4171 bfs&&最短路

2012-05-08 09:18  javaspring  阅读(260)  评论(0编辑  收藏  举报

       这道题一定要读清题意,读懂题的话很好想,没读懂的话就悲剧了。。。。。

       题目中最后说,只有n条边。由于共n+1个点,仅有n条边,而且题目中说了,保证每个点都是可达的,所以必然是一颗树,而且从根节点0到某一节点的路径有且仅有一条。想到这里后,就很容易了,可以用广搜,算出根节点0到每个节点的距离。也可以用最短路算出根节点0到每个节点的距离。

      之后就是选择学校了,设所有边的权值和为sum,则sum*2-dis[i]+num[i],枚举每个点,选出一个最小的即可。

题目:

Paper Route

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 116    Accepted Submission(s): 34


Problem Description
As a poor, tuition-ridden student, you've decided to take up a part time job as a paperboy/papergirl.
You've just been handed your paper route: a set of addresses (conveniently labelled 1 to N).

Every morning, you start at the newspaper office (which happens to be address number 0). You have to plan a route to deliver a newspaper to every address - and you also want to get to class right after you're done.
Conveniently, there are only N roads in your area connecting the addresses, and each of them takes a known time to traverse.
Also, you've precalculated the time it takes to get to Waterloo campus from each address, including the newspaper office (through some combination of biking, busing, or hitching a ride).
How soon can you be done delivering papers and be in your seat at school?
 

Input
Input consists of a number of cases, for each case:
First, there will be a single integer N (the number of addresses, 1 ≤ N ≤ 100,000).
Next, there will be N+1 lines, each with an integer ci (starting with i = 0, 0 ≤ ci ≤ 1,000,000,000), the time it takes to get from location i to campus.
Finally, the input will contain N lines, each with three integers a, b, c (0 ≤ a, b ≤ N, a != b, 0 ≤ c ≤ 1,000). Each of these lines describes a road between locations a and b taking c minutes to traverse.
It is guaranteed that you will be able to reach all the addresses. (Remember that location 0 is the newspaper office.)
 

Output
Output the minimum time it will take to deliver all the papers and get to class.
 

Sample Input
2 1 3 4 0 1 1 0 2 2
 

Sample Output
7

bfs ac代码:

#include <iostream>
#include <string.h>
#include <cstdio>
#include <vector>
#include <queue>

using namespace std;

const int N = 100010;
__int64 num[N],dis[N],num1 = 0,head[N];
struct edge
{
    int rp,value,next;
}ee[N];

void init()
{
    num1 = 0;
    memset(num,0,sizeof(num));
    memset(dis,0,sizeof(dis));
    memset(head,-1,sizeof(head));
}

void addedge(int x,int y,int v)
{
    ee[num1].rp = y;
    ee[num1].value = v;
    ee[num1].next = head[x];
    head[x] = num1++;
}
void bfs(int x)
{
    queue<int> qq;
    qq.push(x);
    while(!qq.empty())
    {
        int y = qq.front();
        qq.pop();
        for(int i = head[y];i != -1;i = ee[i].next)
        {
            int k = ee[i].rp;
            dis[k] = dis[y] + ee[i].value;
            qq.push(k);
        }
    }
}

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        init();
        for(int i = 0;i <= n;++i)
        {
            scanf("%I64d",&num[i]);
        }
        int x,y,value;
        __int64 sum = 0;
        for(int i = 1;i <= n;++i)
        {
            scanf("%d%d%d",&x,&y,&value);
            addedge(x,y,value);
            sum += value;
        }
        bfs(0);
        __int64 mmin = 2000000000;
        __int64 ss = 0;
        for(int i = 0;i <= n;++i)
        {
            ss = (sum - dis[i]) * 2 + num[i] + dis[i];
             if(ss < mmin)
            {
                mmin = ss;
            }
        }
        printf("%I64d\n",mmin);
    }
    return 0;
}

最短路ac代码:

#include <iostream>
#include <string.h>
#include <cstdio>
#include <vector>
#include <queue>

using namespace std;

const int N = 100010;
#define MAX 2000000000
__int64 num[N],dis[N],n,num1 = 0,head[N],insert[N];
int vis[N];
struct edge
{
    __int64 rp,value,next;
}ee[N];

void init()
{
    num1 = 0;
    memset(num,0,sizeof(num));
    memset(vis,0,sizeof(vis));
    memset(head,-1,sizeof(head));
    memset(insert,0,sizeof(insert));
}

void addedge(__int64 x,__int64 y,__int64 v)
{
    ee[num1].rp = y;
    ee[num1].value = v;
    ee[num1].next = head[x];
    head[x] = num1++;
}

void spfa(int x)
{
    queue<__int64> qq;
    qq.push(x);
    memset(vis,0,sizeof(vis));
    for(int i = 0;i <= n;++i)
    {
        dis[i] = MAX;
    }
    dis[0] = 0;
    vis[0] = 1;
    while(!qq.empty())
    {
        __int64 y = qq.front();
        qq.pop();
        for(int i = head[y];i != -1;i = ee[i].next)
        {
            __int64 k = ee[i].rp;
            if(dis[y] + ee[i].value < dis[k])
            {
                dis[k] = dis[y] + ee[i].value;
                if(!vis[k])
                {
                    vis[k] = 1;
                    qq.push(k);
                }
            }
        }
    }
}

int main()
{
    while(~scanf("%d",&n))
    {
        init();
        for(int i = 0;i <= n;++i)
        {
            scanf("%I64d",&num[i]);
        }
        __int64 x,y,value;
        __int64 sum = 0;
        for(int i = 1;i <= n;++i)
        {
            scanf("%I64d%I64d%I64d",&x,&y,&value);
            addedge(x,y,value);
            sum += value;
            insert[y] = value;
        }
        spfa(0);
        __int64 mmin = MAX;
        __int64 ss = 0;
        sum *= 2;
        for(int i = 0;i <= n;++i)
        {
            ss = sum - dis[i] + num[i];
            if(ss < mmin)
            {
                mmin = ss;
            }
        }
        printf("%I64d\n",mmin);
    }
    return 0;
}