Aizu - 2249 Road Construction

题目:给出若干个建筑之间的一些路,每条路都有对应的长度和需要的花费,问在保证源点1到其他个点的距离最短的情况下,最少的花费是多少/

思路:和一般的最短路问题相比,多了一个 数组id【i】,用来记录到达i点在距离最短的情况下是由那条边到达的。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#include<set>
#include<queue>
#include<string>
#include<algorithm>
#define MAXSIZE 1000005
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;

//给出若干个建筑之间的一些路,每条路都有对应的长度和需要的花费,
//问在保证源点1 到其他个点的距离最短的情况下,最少的花费是多少

int n,m,vis[MAXSIZE],a[MAXSIZE],k,dist[MAXSIZE],id[MAXSIZE];

struct node
{
    int u;
    int v;
    int w;
    int c;
    int next;
}G[MAXSIZE];

void Add(int u,int v,int w,int c)
{
    G[k].u = u;
    G[k].v = v;
    G[k].w = w;
    G[k].c = c;
    G[k].next = a[u];
    a[u] = k++;
}

int dij()
{
    memset(vis,0,sizeof(vis));
    memset(id,-1,sizeof(id));
    dist[1] = 0;
    int minn ,p;
    for(int i=1;i<k;i++)
    {
        minn = INF;
        for(int j=1;j<=n;j++)
        {
            if(!vis[j] && dist[j] < minn)
            {
                minn = dist[j];
                p = j;
            }
        }

        if(minn == INF)
            break;
        vis[p] = 1;
        for(int j=a[p];j!=-1;j=G[j].next)
        {
            int v = G[j].v;
            if(dist[v] > dist[p] + G[j].w && !vis[v]) //距离更短就更新
            {
                dist[v] = dist[p] + G[j].w;
                id[v] = j;
            }

            //距离相同,花费更小就更新
            else if(id[v]!=-1 && dist[v] == dist[p] + G[j].w && G[j].c < G[id[v]].c && !vis[v])
            {
                id[v] = j;
            }
        }
    }

    int sum=0;
    for(int i=1;i<=n;i++)
    {
        if(id[i] == -1)
            continue;
        else
            sum += G[id[i]].c;
    }
    return sum;
}

void Init()
{
    memset(a,-1,sizeof(a));
    memset(vis,0,sizeof(vis));
    for(int i=0;i<MAXSIZE;i++)
        dist[i] = INF;
    k = 1;
}

int main()
{
    int u,v,w,c;
    while(scanf("%d%d",&n,&m),n+m)
    {
        Init();

        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d%d",&u,&v,&w,&c);
            Add(u,v,w,c);
            Add(v,u,w,c);
        }

        int ans = dij();

        printf("%d\n",ans);
    }
    return 0;
}

时间: 2024-12-14 06:01:00

Aizu - 2249 Road Construction的相关文章

AOJ 2249 Road Construction (dijkstra)

某国王需要修路,王国有一个首都和多个城市,需要修路.已经有修路计划了,但是修路费用太高. 为了减少修路费用,国王决定从计划中去掉一些路,但是需要满足一下两点: 保证所有城市都能连通 所有城市到首都的最短路不变 思路: 在Dijkstra找最短路的时候,就记录一下费用 if(d[e.to] > d[v] + e.dist) { ... prev_min_cost[e.to] = e.cost; // 最短路必经之路,则费用也必须要 } else if(d[e.to] == d[v] + e.dis

POJ 3352 Road Construction(图论-tarjan)

Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8647   Accepted: 4318 Description It's almost summer time, and that means that it's almost summer construction time! This year, the good people who are in charge of the ro

poj 3352 Road Construction【边双连通求最少加多少条边使图双连通&amp;&amp;缩点】

Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10141   Accepted: 5031 Description It's almost summer time, and that means that it's almost summer construction time! This year, the good people who are in charge of the r

POJ 3352 Road Construction 使得无向图边变双连通图

点击打开链接 Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8168   Accepted: 4106 Description It's almost summer time, and that means that it's almost summer construction time! This year, the good people who are in charge of

POJ 题目 Road Construction(双连通)

Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9353   Accepted: 4648 Description It's almost summer time, and that means that it's almost summer construction time! This year, the good people who are in charge of the ro

POJ 3177 Redundant Paths POJ 3352 Road Construction(双连通)

POJ 3177 Redundant Paths POJ 3352 Road Construction 题目链接 题意:两题一样的,一份代码能交,给定一个连通无向图,问加几条边能使得图变成一个双连通图 思路:先求双连通,缩点后,计算入度为1的个数,然后(个数 + 1) / 2 就是答案(这题由于是只有一个连通块所以可以这么搞,如果有多个,就不能这样搞了) 代码: #include <cstdio> #include <cstring> #include <algorithm&

Road Construction POJ - 3352 (边双连通分量)

Road Construction POJ - 3352 题意:一个无向图(无重边),问至少还要加多少边使得去掉任意一条边后任意两点仍可互达. 无向图的边双连通分量(无重边) 先用一次dfs标记出割边,然后dfs标记出各联通分量 再根据割边,缩点重新建图,生成一颗树 则答案就是(叶子树+1)/2. 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring

Poj 3352 Road Construction &amp; Poj 3177 Redundant Paths(边双连通分量+缩点)

Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9465   Accepted: 4699 Description It's almost summer time, and that means that it's almost summer construction time! This year, the good people who are in charge of the ro

【连通图|边双连通+缩点】POJ-3352 Road Construction

Road Construction Time Limit: 2000MS Memory Limit: 65536K Description It's almost summer time, and that means that it's almost summer construction time! This year, the good people who are in charge of the roads on the tropical island paradise of Remo