当前位置:编程学习 > C/C++ >>

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++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,