[HDU 4118]Holiday's Accommodation[圖論][非遞迴dfs]

來源:互聯網
上載者:User

題意:

有一棵樹, 節點表示城市, 每個城市有一個人. 人們要旅行到其他城市. 相當於一個置換. 求總的路程最大值.

思路:

ans = Σ (每條路長 l )*(經過這條路的最大次數 f )

f = 2 * 這條邊左邊節點數和右邊節點數最小值k. (這樣左邊的每一個點一定能夠對應右邊的某個點)

這個k可以dfs 求得.

但是直接dfs 會爆棧...

需要將其改為非遞迴...

#include <stdio.h>#include <cstring>#include <stack>using namespace std;struct gtype{    int y,d,next;} g[200010];int first[100100],tot,a[100100],tt,x,y,d,n;bool v[100100];inline int min(int a,int b){    if (a<b) return a;    else return b;}void add(int x,int y,int d){    tot++;    g[tot].d=d;    g[tot].y=y;    g[tot].next=first[x];    first[x]=tot;    tot++;    g[tot].d=d;    g[tot].y=x;    g[tot].next=first[y];    first[y]=tot;}void dfs(int p){    stack <int> stk;    int t=first[p];    stk.push(p);    v[p]=true;    while (1)    {        if (t==-1)//該點的所有邊已經遍曆完        {            int y = stk.top();            stk.pop();            if (stk.empty()) break;//dfs結束            a[stk.top()]+=a[y];            //該點的子樹節點數加到其父節點上, 表示該節點相對其父節點已經處理完        }        int x = stk.top();///每次從棧頂取出元素!!        t = first[x];        while (t!=-1)        {            if (!v[g[t].y])            {                v[g[t].y]=true;                stk.push(g[t].y);                break;///一旦前進,便跳出,繼續判斷或者取棧頂元素.否則就相當於bfs了!!!            }            t=g[t].next;        }    }}int main(){    scanf("%d",&tt);    for (int cas=1; cas<=tt; cas++)    {        tot=0;        memset(g,0,sizeof(g));        memset(first,-1,sizeof(first));        scanf("%d",&n);        for (int i=1; i<n; i++)        {            scanf("%d%d%d",&x,&y,&d);            add(x,y,d);        }        for (int i=1; i<=n; i++) a[i]=1;//記錄節點的兒子數,初始化時已經算上了自己        memset(v,0,sizeof(v));        dfs(1);//填a數組        __int64 ans=0;        for (int i=1; i<=2*(n-1); i+=2)        {//遍曆池子,即遍曆每一條邊            x=g[i].y;            y=g[i+1].y;            d=min(a[x],a[y]);            ans+=min(d,n-d)*2*g[i].d;        }        printf("Case #%d: %I64d\n",cas,ans);    }    return 0;}

自己敲一遍. 尤其要感受一下是如何改非遞迴的!

#include <cstdio>#include <cstring>#include <algorithm>#include <stack>using namespace std;const int MAXN = 100005;typedef long long ll;struct edge{    int v, w, next;}g[MAXN<<1];int head[MAXN],num;int a[MAXN];bool vis[MAXN];int n;stack<int> s;void add(int u, int v, int w){    g[++num].v = v;    g[num].w = w;    g[num].next = head[u];    head[u] = num;    g[++num].v = u;    g[num].w = w;    g[num].next = head[v];    head[v] = num;}void dfs(int k){    memset(vis,false,sizeof(vis));    vis[k] = true;    s.push(k);    int t = head[k];    while(true)    {        if(!t)        {            int u = s.top();            s.pop();//deal with tmp node            if(s.empty())   break;            a[s.top()] += a[u];        }        int u = s.top();        t = head[u];        while(t)        {            if(!vis[g[t].v])            {                vis[g[t].v] = true;                s.push(g[t].v);                break;            }            t = g[t].next;        }    }}int main(){    int T,cas = 0;    scanf("%d",&T);    while(T--)    {        num = 0;        memset(head,0,sizeof(head));        memset(g,0,sizeof(g));        scanf("%d",&n);        for(int i=1;i<n;i++)        {            int u,v,w;            scanf("%d%d%d",&u,&v,&w);            add(u,v,w);        }        for(int i=1;i<=n;i++)   a[i] = 1;        dfs(1);        ll ans = 0;        for(int i=1;i<2*(n-1);i+=2)        {            int u = g[i].v;            int v = g[i+1].v;            int k = min(a[u],a[v]);//a記錄子樹大小,較小的那個是"一邊的節點數"            ans += 2ll*min(k,n-k)*g[i].w;//n-k是對面的個數        }        printf("Case #%d: %I64d\n",++cas,ans);    }}

/* 自律 專註 保持活力 */

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.