1. 程式人生 > >暢通工程之區域性最小花費問題(35 分)

暢通工程之區域性最小花費問題(35 分)

這個也是最小生成樹,這個區域性最小,就是有一些最小生成樹 上的路徑已經建成了,所以就不需要花費了,所以,直接建圖的時候,直接把已經建成的路的花費更新為零,剩下的就是板子了。

某地區經過對城鎮交通狀況的調查,得到現有城鎮間快速道路的統計資料,並提出“暢通工程”的目標:使整個地區任何兩個城鎮間都可以實現快速交通(但不一定有直接的快速道路相連,只要互相間接通過快速路可達即可)。現得到城鎮道路統計表,表中列出了任意兩城鎮間修建快速路的費用,以及該道路是否已經修通的狀態。現請你編寫程式,計算出全地區暢通需要的最低成本。

輸入格式:

輸入的第一行給出村莊數目N (1);隨後的(行對應村莊間道路的成本及修建狀態:每行給出4個正整數,分別是兩個村莊的編號(從1編號到N

),此兩村莊間道路的成本,以及修建狀態 — 1表示已建,0表示未建。

輸出格式:

輸出全省暢通需要的最低成本

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <math.h>
#include <stack>
#include <utility>
#include <string>
#include <sstream>
#include <cstdlib>
#include <set>
#define LL long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 10000 + 10;
int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
struct Edge
{
    int from;
    int to;
    int cost;
    Edge(int x = 0,int y = 0,int w = 0)
    {
        from = x;
        to = y;
        cost = w;
    }
} edge[maxn];
int par[1000];
int Find(int x)
{
    if(x == par[x])
        return x;
    else
        return par[x] = Find(par[x]);
}
bool cmp(Edge a,Edge b)
{
    return a.cost < b.cost;
}
int main()
{
    int m,n;
    scanf("%d",&m);
    n = m *(m - 1) / 2;
    for(int i = 0; i <= 1000; i++)
    {
        par[i] = i;

    }
    for(int i = 0; i < n; i++)
    {
        int index;
        scanf("%d %d %d",&edge[i].from,&edge[i].to,&edge[i].cost);
        scanf("%d",&index);
        if(index)
            edge[i].cost = 0;
    }
    sort(edge,edge+n,cmp);
    int sum = 0;
    for(int i = 0; i < n; i++)
    {
        int x = Find(edge[i].from);
        int y = Find(edge[i].to);
        if(x != y)
        {
            par[x] = y;
            sum+= edge[i].cost;
        }

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