Codeforces难题精选
有时侯越是深入,越难看清,不如置身世外,跟着感觉走。
我们记答案为
其实我们都不难感觉到,大概要找一个接近一种货币
方法是设定一个最下界货币
关键变成了枚举这个
确定了合法的
嗯,然后就结束了。其实看到这里你肯定还是不明白,没关系,因为我也不明白。冗杂的证明看不来,尚且能根据人类的推理能力得出答案。
其实世界就是这样呢,有时候不需要知道为什么,也会勇敢地尝试。
简化题面:给定一个
先考虑普通的树怎么做:U285295 的 & 树 。
以一号点为根,怎么求出他到其他点的距离?也许可以树形
void work(int u,int fa){
sze[u]=1;
for(int i=head[u];i;i=last[i]){
int v=to[i];if(v==fa || bk[v]==2)continue;//暂时忽略bk[v]==2
work(v,u);
sze[u]+=sze[v];
dp[u]+=dp[v]+w[i]*sze[v];
}
return;
}
然后呢?然后是换根
void tree_dp(int u,int fa){
ans[u]=dp[u];
for(int i=head[u];i;i=last[i]){
int v=to[i];if(v==fa || bk[v]==2)continue;//暂时忽略bk[v]==2
int r1=dp[u],r2=sze[u],r3=dp[v],r4=sze[v];
dp[u]-=dp[v]+sze[v]*w[i];sze[u]=n-sze[v];
dp[v]+=dp[u]+sze[u]*w[i];sze[v]=n;
tree_dp(v,u);
dp[u]=r1,sze[u]=r2;
dp[v]=r3,sze[v]=r4;//还原
}
return;
}
完成这些后即可通过弱化版的此题。
接下来考虑基环树上:
首先找环,这里不多说了。
然后对环上每个点向它的子树做一次树形
接下来考虑以
显然有一个性质,对于点
简化题面:给定基环树(森林),每个点被染为白或黑色,求基环树的最大匹配,且此时黑色与白色的匹配数量最大。
还是先考虑树上怎么做,考虑树形
然后考虑基环树,显然我们可以删掉一条边变成一棵树,然后枚举这条边选不选,即可得到答案(其实我不是这么写的,但思路大致相同)。
最后提一些细节,如果出现基环树变树的情况,请一定要去重边;以及我
且不说怎么推概率,欺骗策略真的很好玩。
这里主要写一下纳什均衡。
任何一位玩家在此策略组合下单方面改变自己的策略(其他玩家策略不变)都不会提高自身的收益。
例如这题,(图片来自题解)
显然,当我们确定先手
第一道秒的黑。
如果是一棵树的话,这道题就是一个简单树上
但是它是一棵基环树,我们发现环上的结点很小,可以暴力对于每个点跑一遍环求出环上起点出发时的答案,然后就又是换根。
细节比较多。
Code
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+110;
int read(){
int x=0,f=1;char c=getchar();
while(c>'9' || c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0' && c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
int tot,head[N],last[N],to[N],w[N],ODE[N];
void add(int u,int v,int t){to[++tot]=v,w[tot]=t,last[tot]=head[u],head[u]=tot;return;}
int n,m;
double dp[N],ans[N];//dp为向子树走的期望路径
int bk[N],from[N],fedge[N],FoundCircle;vector<int>Circle,Cedge;
void FindCircle(int u){
if(FoundCircle)return;
for(int i=head[u];i;i=last[i]){
int v=to[i];if(v==from[u])continue;if(FoundCircle)return;
if(bk[v]){
int pos=u;
while(pos!=v){
bk[pos]=2;
Circle.push_back(pos);
Cedge.push_back(fedge[pos]);
pos=from[pos];
}
bk[v]=2;
Circle.push_back(v);
Cedge.push_back(w[i]);
FoundCircle=1;return;
}
else{
bk[v]=1,from[v]=u,fedge[v]=w[i];
FindCircle(v);
}
}
return;
}
void TreeDp(int u,int fa){
for(int i=head[u];i;i=last[i]){
int v=to[i];if(v==fa || bk[v]==2)continue;
TreeDp(v,u);
dp[u]+=(dp[v]+w[i])*(1.0/(ODE[u]-1-(bk[u]==2)+(fa==-2)));
}
return;
}
double CircleWalk(int u,int End,int Dire){
// cout<<u<<" "<<End<<" "<<Dire<<endl;
if(Dire==1){
int v=(u+1)%Circle.size();
int t1=Circle[u];
if(v==End)return dp[t1];
else return dp[t1]*(ODE[t1]-2)/(ODE[t1]-1)+(CircleWalk(v,End,Dire)+Cedge[u])/(ODE[t1]-1);
}
else{
int v=(u+Circle.size()-1)%Circle.size();
int t1=Circle[u];
if(v==End)return dp[t1];
else return dp[t1]*(ODE[t1]-2)/(ODE[t1]-1)+(CircleWalk(v,End,Dire)+Cedge[v])/(ODE[t1]-1);
}
}
void ChangeRoot(int u,int fa){
ans[u]=dp[u];
// if(u==2){
// for(int i=1;i<=n;i++)cout<<dp[i]<<" ";cout<<endl;
// }
for(int i=head[u];i;i=last[i]){
int v=to[i];if(bk[v]==2 || v==fa)continue;
double RcdDpu=dp[u],RcdDpv=dp[v];
dp[u]-=(dp[v]+w[i])/ODE[u];
if(ODE[u]-1!=0)dp[u]=dp[u]*ODE[u]/(ODE[u]-1);
else dp[u]=0;
dp[v]=dp[v]*(ODE[v]-1)/ODE[v];
dp[v]+=(dp[u]+w[i])/ODE[v];
ChangeRoot(v,u);dp[u]=RcdDpu,dp[v]=RcdDpv;
}
return;
}
void HardWork(){
bk[1]=1,from[1]=-1;
FindCircle(1);
// for(int i=0;i<(int)Circle.size();i++)cout<<Circle[i]<<" ";cout<<endl;
// for(int i=0;i<(int)Circle.size();i++)cout<<Cedge[i]<<" ";cout<<endl;
for(int i=0;i<(int)Circle.size();i++)TreeDp(Circle[i],-1);
for(int i=0;i<(int)Circle.size();i++){
int u=Circle[i];
ans[u]+=dp[u]*(ODE[u]-2)/ODE[u];
ans[u]+=(CircleWalk((i+1)%Circle.size(),i,1)+Cedge[i])/ODE[u];
ans[u]+=(CircleWalk((i+Circle.size()-1)%Circle.size(),i,-1)+Cedge[(i+Circle.size()-1)%Circle.size()])/ODE[u];
}
for(int i=0;i<(int)Circle.size();i++){
int u=Circle[i];
dp[u]=ans[u];
ChangeRoot(u,-1);
}
return;
}
void EasyWork(){
TreeDp(1,-2);
ChangeRoot(1,-1);
return;
}
int main(){
n=read(),m=read();
for(int i=1;i<=m;i++){
int u=read(),v=read(),t=read();
add(u,v,t),add(v,u,t);ODE[u]++;ODE[v]++;
}
if(m==n-1)EasyWork();
else HardWork();
double RealAns=0;
for(int i=1;i<=n;i++)RealAns+=ans[i]/n;
printf("%.5lf\n",RealAns);
return 0;
}
/*
5 5
1 2 1
2 3 2
3 1 3
3 4 4
4 5 4
*/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探