zoukankan      html  css  js  c++  java
  • 3896. 【NOIP2014模拟10.26】战争游戏

    在这里插入图片描述
    鉴于如此一道恶心的题,作者还花了一个晚上草草学了tarjan。
    在这里插入图片描述
    在这里插入图片描述
    于是乎,这道题就是道tarjan
    具体怎么实现呢?正解上有个什么树形DP,看的我一脸懵逼。
    这道题可以运用到tarjan一个高科技的算法叫——割点。
    这里就不再介绍怎么打tarjan了,切入正题。
    我们先回忆下割点。
    也就是在一个无向图中,将一个点G及其相关的边全部扔掉,会使这个图不在联通,便称点G为割点(作者个人理解)
    看完上面的,是不是感觉和题目大意有点相像?
    在这里插入图片描述
    我先在做tarjan的同时可以很轻松的求得其子节点的数量,从而得知联通块的大小(如蓝色圆圈紫色圆圈橙色圆圈)然后很自然的就能求出子节点的方案数
    由上面,也很容易推出绿色圆圈}的方案数

    #include<cstdio>
    #include<algorithm>
    #define N 50001
    using namespace std;
    int n,m,i,x,y,to,t,low[N],ans[N],dfn[N],last[200001],num[N];
    struct node
    {
    	int go,last;
    }p[200001];
    void make(int x,int y){p[++t].go=y;p[t].last=last[x];last[x]=t;}
    void tarjan(int x)
    {
    	num[x]=1; dfn[x]=low[x]=++to;
    	int tot=0;
    	for (int i=last[x];i;i=p[i].last)
    	{
    		int y=p[i].go;
    		if (!dfn[y])
    		{
    			tarjan(y);
    			low[x]=min(low[x],low[y]);
    			if (dfn[x]<=low[y])
    			{
    				ans[x]+=num[y]*(n-1-num[y]);
    				tot+=num[y];
    			}
    			num[x]+=num[y];
    		}else low[x]=min(low[x],dfn[y]);
    	}
    	ans[x]+=tot*(n-1-tot);
    }
    int main()
    {
    	freopen("a.in","r",stdin);
    	scanf("%d%d",&n,&m);
    	for (i=1;i<=m;i++)
    	{
    		scanf("%d%d",&x,&y);
    		make(x,y); make(y,x);
    	}
    	to=0;
    	tarjan(1);
    	for (i=1;i<=n;i++) printf("%d
    ",ans[i]/2+n-1);
    }
    
    
    如果自己说什麽都做不到而什麽都不去做的话,那就更是什麽都做不到,什麽都不会改变,什麽都不会结束.
  • 相关阅读:
    基于NFS实现WordPress
    基于三台主机部署phpwind
    phpMyAdmin安装部署
    配置LAMP实现WordPress
    配置HTTPS服务
    部署DNS服务
    文本三剑客---awk(gawk)基础
    文本三剑客---sed 基础
    2019-2020-1 20199308《Linux内核原理与分析》第七周作业
    2019-2020-1 20199308《Linux内核原理与分析》第六周作业
  • 原文地址:https://www.cnblogs.com/Sport-river/p/10390125.html
Copyright © 2011-2022 走看看