p1453城市環路
最開始是按騎士那道題的做法 只是這道是雙向邊
先dfs一遍判環 根節點一定在環上
然後從根節點出發 強制不選根節點的父親 因為建的是雙向邊dfs來dp的時候會重複算 所以用vis來記錄這個點有沒有走過
然後再來一遍從根節點的父親出發 不選根節點的父親的父親
不知道為啥我第二遍dp的時候沒有清空vis陣列也能過....
my
#includeusing namespace std;
#define ll long long
#define rg register
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)>(y)?(y):(x))
const int n=1e6+5,m=2e5+5,inf=0x3f3f3f3f,p=19650827;
int n,ans=0,a[n],fa[n],f[n][2],rt,frt;
double k;
bool vis[n];
template void rd(t &x)
int head[n],tot=0;
struct edgee[n<<1];
void add(int u,int v),head[u]=tot;
}void dfs(int u,int fa)
else f[u][1]=-inf; }}
void find(int u,int fa)
find(v,u); }}
int main()
另一種用並查集來判斷環並得出根節點和它的父親(**裡好像順序不太對 但都一樣啦
) 這條邊就不連 這樣圖就變成了乙個樹
然後跑兩遍dp 從\(f[rt][0]\)和\(f[frt][0]\)即不選根節點和不選根節點父親中找乙個較大值即為答案
code
#includeusing namespace std;
#define max(x,y) ((x)>(y)?(x):(y))
const int n=1e6+5,m=2e5+5,inf=0x3f3f3f3f,p=19650827;
int n,ans=0,a[n],fa[n],f[n][2],rt,frt;
double k;
bool vis[n];
template void rd(t &x)
int head[n],tot=0;
struct edgee[n<<1];
void add(int u,int v),head[u]=tot;
}void dfs(int u,int ff)
}int find(int x)
int main()
scanf("%lf",&k);
dfs(rt,0),ans=max(ans,f[rt][0]);
dfs(frt,0),ans=max(ans,f[frt][0]);
printf("%.1f",(double)k*ans);
return 0;
}
題解 Luogu1453 城市環路
給你一棵樹,強制要求一條邊只能選乙個點,並且還額外給條邊 s t s,t 說s,t也不能同時選,求最大貢獻 這不是擺明了那你用樹形dp切掉的節奏嗎?設f u 0 1 f u 0 1 表示以u u 為根的字樹,u role presentation u u點選或不選的最大貢獻 然後轉移比較顯然,1.如...
洛谷 P1453 城市環路
給出一幅有n個點,n條邊的無向聯通圖,每乙個點有乙個權,並給出乙個常數k,對其中一些點進行染色,且相鄰兩點的顏色不能都染,則最大的染色點權值和 k是多少.首先題目與k幾乎無關 最後乘上即可 僅僅比樹多了一條邊,因而只有乙個環,只要處理一下這個唯一環即可用樹形dp的思路來做.可以在這個環上找任意兩個相...
基環樹上dp luoguP1453 城市環路
傳送門 quq基環樹上的dp 先dp樹再dp環,然後注意環上還要記錄一維開始那個節點有沒有選,因為最後乙個節點和第乙個也不能衝突 include include include include include include define n 100005 using namespace std i...