hdu 4443 Lost [2012 ACM/ICPC 金华区域赛B题]
这题太恶心了。。。应该是我做过的最难的树形dp,那个圈超恶心。。。区域赛的时候只有两个队过了这道题,一个是上交的秘银,还有一个是北理工的Keshik,无限膜拜他们!!!我的代码有点长。。500多行吧。。大部分是用来调试的,细节比较多,调了一天一夜才ac。。。艹!
然后说下方法吧~
第一步是找出这个圈,怎么找呢?边双联通tarjan算法呗~这个简单
把这个圈拆开,于是形成了3-30颗树,因为题目说圈只有3-30个点
对于每个树进行树形dp,求出往上推的概率(dpx和dps,dps是dpx的总和)
然后在圈上dp,求出圈上每个点互相影响的概率,分顺时针(go)和逆时针(back)
再从圈出发往下推,求出推到每个节点的概率(dpy)
最后统计,有两种点会停止,一种是叶节点,还有一种是圈上度为2的节点,选出前5个相加就好了~o(∩_∩)o ~
#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#include<cmath>
#include<cassert>
#include<cstring>
#include<iomanip>
using namespace std;
#ifdef _WIN32
#define i64 __int64
#define out64 "%I64d\n"
#define in64 "%I64d"
#else
#define i64 long long
#define out64 "%lld\n"
#define in64 "%lld"
#endif
/************ for topcoder by zz1215 *******************/
#define FOR(i,a,b) for( int i = (a) ; i <= (b) ; i ++)
#define FF(i,a) for( int i = 0 ; i < (a) ; i ++)
#define FFD(i,a,b) for( int i = (a) ; i >= (b) ; i --)
#define S64(a) scanf(in64,&a)
#define SS(a) scanf("%d",&a)
#define LL(a) ((a)<<1)
#define RR(a) (((a)<<1)+1)
#define pb push_back
#define pf push_front
#define X first
#define Y second
#define CL(Q) while(!Q.empty())Q.pop()
#define MM(name,what) memset(name,what,sizeof(name))
#define MC(a,b) memcpy(a,b,sizeof(b))
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
#define read freopen("in.txt","r",stdin)
#define write freopen("out.txt","w",stdout)
const int inf = 0x3f3f3f3f;
const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;
const double oo = 10e9;
const double eps = 10e-9;
const double pi = acos(-1.0);
const int maxn = 100011;
vector<int>v[maxn];
vector<int>g[maxn];
vector<int>s;
int n;
double nn;
int t[maxn];
int f[maxn];
int dfn[maxn];
int low[maxn];
int df,nf;
bool ins[maxn];
int tot;
bool hash[maxn];
int yes[33];
double go[33][33];
double back[33][33];
double dpx[maxn];
double dpy[maxn];
bool vis[maxn];
int cnt[maxn];
double dp[maxn];
double dps[maxn];
vector<double>ans;
void tarjan(int now)
{
low[now] = dfn[now] = df++;
s.push_back(now);
ins[now]=true;
int to;
for(int i=0;i<g[now].size();i++)
{
to = g[now][i];
if(!dfn[to])
{
t[to]=now;
tarjan(to);
low[now] = min(low[to],low[now]);
}
else if(to!=t[now])
{
low[now]=min(dfn[to],low[now]);
}
}
if(dfn[now] == low[now])
{
while(s.back() != now)
{
to = s.back();
f[to] = nf;
s.pop_back();
ins[to]=false;
}
to = s.back();
s.pop_back();
ins[to]=false;
f[to] = nf++;
}
return ;
}
void dfs(int now)
{
vis[now] = true;
int to;
for(int i=0;i<g[now].size();i++)
{
to = g[now][i];
if(!ins[to] && !vis[to])
{
cnt[now]++;
}
}
for(int i=0;i<g[now].size();i++)
{
to = g[now][i];
if(!ins[to] && !vis[to])
{
dfs(to);
dps[now]+=dpx[to];
if(ins[now])
补充:软件开发 , C++ ,