1. 程式人生 > >hdu6201 思維+最長路(SPFA或Dijkstra)

hdu6201 思維+最長路(SPFA或Dijkstra)

題意

給你一棵樹,樹上有點權和邊權,讓你選擇起點S到終點T使得T-S-sum最大。(sum是S到T的距離)輸出這個最大值。

題解

這是2017ACM-ICPC瀋陽的網路賽的1008題,這裡不得不吐槽一下這個網路賽的體驗真的很差,好多題的資料都很弱,各種暴力都能過。。。還有個題最差交210必過,直接導致暴力交題,最後OJ都爆了。。。相信很多做過網路賽的都心有餘悸。。。

這題比賽的時候沒做出來,其實轉化一下就是求最長路的題了。我們新建一個點作為源點(我選的是0),然後建源點到n個點的有向邊,邊權為-w[i](w[i]是i點的點權)。之後新建一個點作為匯點(我選的是n+1),建n個點到匯點的有向邊,邊權為w[i]。最後求源點到匯點的最長路即可。這裡用SPFA和Dijkstra(優先佇列優化)均可。

SPFA程式碼

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const int maxn = 1e5+5;
int dist[maxn],in_queue[maxn];
bool vis[maxn];
int n;

struct Edge{
    int to,w,next;
}edge[maxn<<2];
int head[maxn],tot;

void add_edge(int u,int v,int w)
{
    edge[tot].to = v;
    edge[tot].w = w;
    edge[tot].next = head[u];
    head[u] = tot++;
}

bool
SPFA() { int cur,next; queue<int> q; vis[0] = true; in_queue[0]++; dist[0] = 0; q.push(0); while(!q.empty()) { cur = q.front(),q.pop(); vis[cur]=false; for(int i=head[cur];i!=-1;i=edge[i].next) { int to = edge[i].to; int
w = edge[i].w; if(dist[to]<dist[cur]+w) { dist[to] = dist[cur]+w; if(!vis[to]) { in_queue[to]++; if(in_queue[to]>=n+2) return false; q.push(to); vis[to] = true; } } } } return true; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d",&n); tot=0; memset(head,-1,sizeof(head)); memset(dist,-INF,sizeof(dist)); memset(vis,false,sizeof(vis)); memset(in_queue,0,sizeof(in_queue)); int u,v,w; for(int i=1;i<=n;i++) { scanf("%d",&w); add_edge(0,i,-w); add_edge(i,n+1,w); } for(int i=1;i<n;i++) { scanf("%d%d%d",&u,&v,&w); add_edge(u,v,-w); add_edge(v,u,-w); } SPFA(); printf("%d\n",dist[n+1]); } return 0; }

Dijkstra程式碼

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const int maxn = 1e5+5;
typedef pair<int,int> P;
int dist[maxn];
int n;

struct Edge{
    int to,w,next;
}edge[maxn<<2];
int head[maxn],tot;

void add_edge(int u,int v,int w)
{
    edge[tot].to = v;
    edge[tot].w = w;
    edge[tot].next = head[u];
    head[u] = tot++;
}

void Dijkstra()
{
    priority_queue<P> pq;
    P p;
    dist[0]=0;
    pq.push(P(dist[0],0));
    while(!pq.empty())
    {
        p = pq.top(),pq.pop();
        int u = p.second;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v = edge[i].to;
            int w = edge[i].w;
            if(dist[v]<dist[u]+w)
            {
                dist[v] = dist[u]+w;
                pq.push(P(dist[v],v));
            }
        }
    }
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        tot=0;
        memset(head,-1,sizeof(head));
        memset(dist,-INF,sizeof(dist));
        int u,v,w;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&w);
            add_edge(0,i,-w);
            add_edge(i,n+1,w);
        }
        for(int i=1;i<n;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            add_edge(u,v,-w);
            add_edge(v,u,-w);
        }
        Dijkstra();
        printf("%d\n",dist[n+1]);
    }
    return 0;
}

上面是Dijkstra程式碼的,下面是SPFA程式碼的,這題是SPFA跑得快記憶體也少。

相關推薦

hdu6201 思維+SPFADijkstra

題意 給你一棵樹,樹上有點權和邊權,讓你選擇起點S到終點T使得T-S-sum最大。(sum是S到T的距離)輸出這個最大值。 題解 這是2017ACM-ICPC瀋陽的網路賽的1008題,這裡不得不吐槽一下這個網路賽的體驗真的很差,好多題的資料都很弱,各種

51nod 1624 取餘 set+二分查詢 真.好題

思路: 核心思路是寫出結果的表示式,發現只有兩個變數,所以可以列舉一個變數二分查詢另一個變數。由於依靠結果的表示式,我感覺這個題的思路不好想。 首先說,因為取模後會有後效性,或者說區域性最優不

思維-】hdu 3696 Farm Game

“Farm Game” is one of the most popular games in online community. In the community each player has a virtual farm. The farmer can decide to plant some kin

LeetCode 845. 陣列中的山脈C++、python

我們把陣列 A 中符合下列屬性的任意連續子陣列 B 稱為 “山脈”: B.length >= 3 存在 0 < i < B.length - 1 使得 B[0] < B[1] < ... B[i-1] < B

演算法百題001:平臺The Longest Plateau問題

找出已排序陣列中的最長平臺。平臺是連續的一串值相同的元素,如1,2,2,3中[1], [2, 2], [3]都是平臺。 方案一:常規思路,利用STL的map容器統計每個元素的出現頻數,然後從map容器中選出頻數最大的元素。 /* * Function: longest_

線段幾何證明題

最長線段(chord.pas/chord.in/chord.out) (LYOI資訊學綜合模擬20090321Problem 1) 問題描述 給定兩個圓各自的圓心座標和半徑長。過其中一個交

短路演算法Floyd、Dijkstra

         本節學習指定一個點(源點)到其餘各個頂點的最短路徑,也叫做“單源最短路徑”。例如下圖中的1號頂點到2、3、4、5、6號頂點的最短路徑。        與Floyd演算法一樣,這裡仍然使用二維陣列g來儲存頂點之間邊的關係,初始值如下:        我們還需要用一個一維陣列dis來儲存1號頂點

poj 1932 XYZZYspfa+判斷正環+floyd求傳遞閉包

XYZZY Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 4154   Accepted: 1185

HDU 3249 Test for job 有向無環圖上的,DP

code head struct sin == cout article scanf for ?? 解題思路: 求有向無環圖上的最長路。簡單的動態規劃#include <iostream> #include <cstring> #include

P1807 _NOI導刊2010提高07

接下來 for pac ext 輸入輸出 etc while out string 洛谷——P1807 最長路_NOI導刊2010提高(07) 題目描述 設G為有n個頂點的有向無環圖,G中各頂點的編號為1到n,且當為G中的一條邊時有i <

POJ 3592--Instantaneous Transference【SCC縮點新建圖 &amp;&amp; SPFA &amp;&amp; 經典】

col describe sca 搜索 hat style ecif test csdn Instantaneous Transference Time Limit: 5000MS Memory Limit: 65536K

2017CCPC中南地區賽 H題

main art spa fine sca using push_back ear 端點 題目地址:202.197.224.59/OnlineJudge2/ 來自湘潭大學OJ,題號:1267。 這裏用到了一個樹的直徑(樹中的最長邊)的結論:當你找到一棵樹的最長邊後,這個樹中

POJ.1752.Advertisement(差分約束 SPFA)

pos 分享 inf Go problem 技術 pty const jks 題目鏈接 \(Description\) 有n個人在一條直線上跑步,每個人的起點 \(Si\)、終點 \(Ei\) 已知;每個點可以放一個廣告牌,一個人i能看到的廣告牌數量為 \(Ei-Si+1\

noip 2009 優貿易短路+反向

輸出 main 路線 ins 城市 mes 部分 cst don 題目描述 C 國有 n 個大城市和 m 條道路,每條道路連接這 n 個城市中的某兩個城市。任意兩個城市之間最多只有一條道路直接相連。這 m 條道路中有一部分為單向通行的道路,一部分為雙向通行的道路,雙向通行

HDU 6201【+SPFA轉化為流問題求解***】

.com ID printf head eof namespace 題意 scanf pop 題意: 給出一棵生成樹,每個點有一個權值,代表商品的售價,樹上每一條邊上也有一個權值,代表從這條邊經過所需要的花費。現在需要你在樹上選擇兩個點,一個作為買入商品的點,一個作為賣出商

The Largest Clique UVA - 11324 強連通分量 + dp

強連通分量 top 起點 printf push fin clas int clu 這題 我剛開始想的是 縮點後 求出入度和出度為0 的點 然後統計個數 用總個數 減去 然而 這樣是不可以的 畫個圖就明白了。。。 如果 減去度為0的點 那麽最後如果出現這

題解報告:hdu 4607 Park Visit+規律

inpu follow nodes 一點 dfs ems ios eno sca Problem Description Claire and her little friend, ykwd, are travelling in Shevchenko‘s Park! The

【題解】[牛客網NOIP賽前集訓營-提高組第六場]A. 拓撲排序

題目連結 #include<cstdio> #include<queue> #include<cstring> using namespace std; const int N=1e6+10,mod=998244353; st

bzoj1880: [Sdoi2009]Elaxia的路線(spfa,拓撲排序)

1880: [Sdoi2009]Elaxia的路線 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 1944  Solved: 759[Submit][Status][Disc

BZOJ5450: 轟炸水題,Tarjan縮點求

5450: 轟炸 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 43  Solved:18[Submit][Status][Discuss] Description 有n座