UVA1494Qin Shi Huang’s National Road System(LA5713)(HDU4081)

來源:互聯網
上載者:User

次小產生樹的應用

總思路是枚舉每條邊作為那條免費的路;

當你確定一條免費的路之後,相當於在這兩個點之間加了一條長度為0的邊之後求MST;

根據劉汝佳所說,MST就是把所有環中的最大邊刪除,我們首先要求出MST

如果枚舉的邊屬於MST,則他原來不是環上的最大邊,現在也不是,該這條邊為0後MST的結構不變,只是MST的總長度少了這條邊的長度;  

 如果枚舉的邊不屬於MST,則他原來肯定是某個環上的最大邊,這條邊長度為0之後刪除的“最大邊”就是原來環上的第二大的邊,也就是原MST結構中這兩個點之間的最大邊;

在求出MST後我們可以預先處理求出所有(i, j)之間的最大邊

所求的MST需要這些內容

//1.某邊是否屬於MST

//2.MST上沒兩個點間的最大邊
//3.MST的鄰接表,用於求所有(i, j)之間的最大邊

#include <stdio.h>#include <string.h>#include <math.h>#include <algorithm>#include <vector>#include <queue>using namespace std;const int maxn = 1000+10;struct Node{    int from, to;    double dist;    Node(int from, int to, double dist)    {        this->from = from;        this->to = to;        this->dist = dist;    }    bool operator<(const struct Node &ans)const    {        return dist > ans.dist;    }};double popu[maxn], edge[maxn][maxn], sum;int x[maxn], y[maxn];bool vis[maxn], flag[maxn][maxn];//是否屬於樹double dist[maxn];vector<int> adj[maxn];//MST的鄰接表double EdgeM[maxn][maxn];//每兩個點間的最大邊int tcase, n;void Init(){    scanf("%d", &n);    for(int i = 1; i <= n; i++)        scanf("%d%d%lf", &x[i], &y[i], &popu[i]);    for(int i = 1; i <= n; i++)        for(int j = 1; j <= n; j++)        {            double xx = x[i] - x[j];            double yy = y[i] - y[j];            edge[i][j] = sqrt(xx*xx+yy*yy);        }}void Prim(){    priority_queue<struct Node> myQue;    for(int i = 1; i <= n; i++)    {        dist[i] = -1;        vis[i] = false;        adj[i].clear();        memset(flag[i], false, sizeof(flag[i]));    }    sum = 0;//MST的總長度    dist[1] = 0;    vis[1] = true;    for(int i = 2; i <= n; i++)//以1為起始集合    {        dist[i] = edge[1][i];        myQue.push(Node(1, i, dist[i]));    }    while(!myQue.empty())    {        struct Node ans = myQue.top();        myQue.pop();        int f = ans.from;        int u = ans.to;        if(vis[u])            continue;        sum += edge[f][u];        vis[u] = true;//改點已經加入MST了        flag[f][u] = flag[u][f] = true;        adj[u].push_back(f);        adj[f].push_back(u);        for(int v = 1; v <= n; v++)            if((v != u && !vis[v]) && (dist[v] == -1 || dist[v] > edge[u][v]))            {                dist[v] = edge[u][v];                myQue.push(Node(u, v, dist[v]));            }    }}void DFS(int root, int cur, double MM){    EdgeM[root][cur] = MM;    vis[cur] = true;    for(vector<int>::iterator it = adj[cur].begin(); it != adj[cur].end(); it++)        if(!vis[*it])            DFS(root, *it, max(MM, edge[cur][*it]));}void Solve(){    for(int i = 1; i <= n; i++)    {        memset(vis, false, sizeof(vis));        DFS(i, i, 0);    }    double ans = -1;    for(int i = 1; i <= n; i++)        for(int j = 1; j < i; j++)//枚舉super的那條路        {            if(flag[i][j])                ans = max(ans, (popu[i]+popu[j])/(sum-edge[i][j]));            else                ans = max(ans, (popu[i]+popu[j])/(sum-EdgeM[i][j]));        }    printf("%.2lf\n", ans);}int main(){    scanf("%d", &tcase);    while(tcase--)    {        Init();        Prim();        Solve();    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.