[雅礼集训6-23] T1 电报
2017-06-23 21:57
155 查看
每个点都只连向一个点,所以最终的图就是若干个基环树,原问题等价于在基环树中选出若干条互不相交的链,使链顶权值和最小,对每个基环树DP即可。
树型DP:设dp[i]表示点i及其子树中的答案,mx[i]表示max{c[son]},son为i的儿子,那么dp[i]=∑(dp[son]-mx[i])+c[i]。复杂度O(n)
环上DP:先枚举环的起始点s,且s->pre(c)的边断掉。设f[i]为s~i的答案和,那么f[i]=min{f[i-1],f[pre(i)]+mx[pre(i)]-c[i]}+dp[i],前一种情况表示从i和pre(i)的边断掉,即从i处重开一条链;后一种情况表示不断,那么pre(i)的子树就要与环上的主链断开。复杂度O(n^2)。还可以优化到O(n)。
O(n^2)做法:
树型DP:设dp[i]表示点i及其子树中的答案,mx[i]表示max{c[son]},son为i的儿子,那么dp[i]=∑(dp[son]-mx[i])+c[i]。复杂度O(n)
环上DP:先枚举环的起始点s,且s->pre(c)的边断掉。设f[i]为s~i的答案和,那么f[i]=min{f[i-1],f[pre(i)]+mx[pre(i)]-c[i]}+dp[i],前一种情况表示从i和pre(i)的边断掉,即从i处重开一条链;后一种情况表示不断,那么pre(i)的子树就要与环上的主链断开。复杂度O(n^2)。还可以优化到O(n)。
O(n^2)做法:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const int maxn=100100; int n,top,to[maxn],huan[maxn]; bool visit[maxn],pd,b[maxn]; ll ans=0,now,minf,c[maxn],dp[maxn],mx[maxn],f[maxn]; struct edge { int t; ll w; edge *next; }*con[maxn]; bool tepan() { memset(visit,0,sizeof(visit)); int p=1; while(!visit[p]){visit[p]=1;p=to[p];} for(int i=1;i<=n;i++) if(!visit[i]) return 0; return 1; } void ins(int x,int y) { edge *p; p=new edge; p->t=y; p->next=con[x]; con[x]=p; } void find(int v) { visit[v]=1; if(!visit[to[v]]) find(to[v]); else pd=1; if(pd) {huan[++top]=v;b[v]=1;} if(to[huan[1]]==v) pd=0; visit[v]=0; } void dfs(int v) { visit[v]=1; mx[v]=0; dp[v]=c[v]; for(edge *p=con[v];p!=NULL;p=p->next) if(!b[p->t]) { dfs(p->t); mx[v]=max(mx[v],c[p->t]); dp[v]+=dp[p->t]; } dp[v]-=mx[v]; } int p(int x){return (x==1)?top:(x-1);} int s(int x){return (x==top)?1:(x+1);} int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%lld",&to[i],&c[i]); ins(to[i],i); } if (tepan()) ans=0; else { memset(b,0,sizeof(b)); memset(dp,0,sizeof(dp)); memset(visit,0,sizeof(visit)); for(int i=1;i<=n;i++) if(!visit[i]) { top=0; now=1e15; find(i); for(int j=1;j<=top;j++) dfs(huan[j]); for(int j=1;j<=top;j++) { f[j]=dp[huan[j]]; for(int k=s(j);k!=j;k=s(k)) f[k]=min(f[p(k)]+dp[huan[k]],f[p(k)]+mx[huan[p(k)]]+dp[huan[k]]-c[huan[k]]); now=min(now,f[p(j)]); } ans+=now; } } printf("%lld\n",ans); return 0; }
相关文章推荐
- 「6月雅礼集训 2017 Day7」电报
- loj6043 「雅礼集训 2017 Day7」蛐蛐国的修墙方案
- 「6月雅礼集训 2017 Day7」三明治
- 「6月雅礼集训 2017 Day11」tree
- LOJ 6045. 「雅礼集训 2017 Day8」价(最大闭合子图)
- 雅礼集训1.4 序列
- loj6030 「雅礼集训 2017 Day1」矩阵
- 「6月雅礼集训 2017 Day11」jump
- LibreOJ#6030. 「雅礼集训 2017 Day1」矩阵
- 雅礼集训 小C的锦标赛
- [2018雅礼集训1-23]盛大的庆典 状压DP
- [雅礼集训]bsh(分治)
- [2018雅礼集训1-23]ete 分块
- loj6029 「雅礼集训 2017 Day1」市场
- 「6月雅礼集训 2017 Day1」说无可说
- 「6月雅礼集训 2017 Day11」delight
- 雅礼集训暴力大神hxx
- 雅礼集训及WC2018划水记
- 【2017国庆雅礼集训划水记】 day1 四边形不等式