zoukankan      html  css  js  c++  java
  • 世界「theworld」

    前言

    随机化不适合我。

    题目

    随机给 \(n\) 个点 \(m\) 条边,点有正权,边有负权,求权值最大的诱导子图的权值。

    \(1\le n\le 10^5;0\le m\le \frac{n}{2}.\)

    讲解

    首先如果不是随机的,那么这个问题和最大独立集差不多,直接嗝屁。

    但是它是随机的,而且边很少,图很稀疏,所以环就特别少,直接跑出dfs树然后枚举返祖边上的点选不选,树形dp即可。

    大样例甚至就是森林。

    时间复杂度 \(O(n)\)?

    代码

    甚至只写树的部分都有45pts
    //12252024832524
    #include <bits/stdc++.h>
    #define TT template<typename T>
    using namespace std;
    
    typedef long long LL;
    const int MAXN = 200005;
    const LL INF = 12345678910111ll;
    const int p = 1e9+7;
    const int q = 101;
    const int b = 137;
    map<pair<int,int>,int> me;
    int n,m,x[MAXN],y[MAXN],a[MAXN],U[MAXN],V[MAXN],W[MAXN],d[MAXN];
    
    LL Read()
    {
    	LL 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*10)+(c^48);c = getchar();}
    	return x * f;
    }
    TT void Put1(T x)
    {
    	if(x > 9) Put1(x/10);
    	putchar(x%10^48);
    }
    TT void Put(T x,char c = -1)
    {
    	if(x < 0) putchar('-'),x = -x;
    	Put1(x); if(c >= 0) putchar(c);
    }
    TT T Max(T x,T y){return x > y ? x : y;}
    TT T Min(T x,T y){return x < y ? x : y;}
    TT T Abs(T x){return x < 0 ? -x : x;}
    
    int head[MAXN],tot;
    struct edge
    {
    	int v,w,nxt;
    }e[MAXN<<1];
    void Add_Edge(int u,int v,int w)
    {
    	e[++tot] = edge{v,w,head[u]};
    	head[u] = tot;
    }
    void Add_Double_Edge(int u,int v,int w)
    {
    	Add_Edge(u,v,w);
    	Add_Edge(v,u,w); 
    }
    
    bool vis[MAXN];
    int s[MAXN],tl,fs[MAXN],tt,ptot,val[MAXN];
    pair<int,int> pp[MAXN];
    void dfs1(int x,int fa)
    {
    	vis[x] = 1; s[++tl] = x; d[x] = d[fa] + 1;
    	for(int i = head[x]; i ;i = e[i].nxt)
    		if(!vis[e[i].v]) dfs1(e[i].v,x);
    		else if(e[i].v != fa && d[e[i].v] < d[x]) fs[++tt] = x,fs[++tt] = e[i].v,pp[++ptot] = make_pair(x,e[i].v),val[ptot] = e[i].w;
    }
    LL dp[MAXN][2];
    void dfs2(int x)
    {
    	dp[x][1] += a[x];
    	for(int i = head[x],v; i ;i = e[i].nxt)
    		if(d[v = e[i].v] == d[x] + 1)
    		{
    			dfs2(v);
    			dp[x][0] += Max(dp[v][0],dp[v][1]);
    			dp[x][1] += Max(dp[v][0],dp[v][1]-e[i].w);
    		}
    }
    
    int main()
    {
    	freopen("theworld.in","r",stdin);
    	freopen("theworld.out","w",stdout);
    	n = Read(); m = Read(); x[0] = Read(); y[0] = Read(); a[0] = Read(); W[0] = Read();
    	for(int i = 1;i <= n;++ i) a[i] = (1ll*q*a[i-1]+b)%p;
    	for(int i = 1;i <= m;++ i)
    	{
    		x[i] = (1ll*q*x[i-1]+b)%p;
    		y[i] = (1ll*q*y[i-1]+b)%p;
    		W[i] = (1ll*q*W[i-1]+b)%p;
    		U[i] = x[i]%n+1,V[i] = y[i]%n+1;
    		if((U[i]^V[i]) && !me[make_pair(U[i],V[i])])
    			me[make_pair(U[i],V[i])] = me[make_pair(V[i],U[i])] = 1,Add_Double_Edge(U[i],V[i],W[i]);
    	}
    	LL ans = 0;
    	for(int i = 1;i <= n;++ i) 
    	{
    		if(vis[i]) continue;
    		ptot = tl = tt = 0;
    		dfs1(i,0);
    		if(tt) 
    		{
    			LL MAX = 0;
    			sort(fs+1,fs+tt+1); tt = unique(fs+1,fs+tt+1)-fs-1;
    			for(int S = 0;S < (1<<tt);++ S)
    			{
    				for(int j = 1;j <= tl;++ j) dp[s[j]][0] = dp[s[j]][1] = 0;
    				for(int j = 0;j < tt;++ j)
    					if(S >> j & 1) dp[fs[j+1]][1] = INF,dp[fs[j+1]][0] = -INF;
    					else dp[fs[j+1]][1] = -INF,dp[fs[j+1]][0] = INF;
    				for(int j = 1;j <= ptot;++ j)
    					if(dp[pp[j].first][1] > 0 && dp[pp[j].second][1] > 0)
    						dp[pp[j].first][1] -= val[j];
    				dfs2(i); MAX = Max(MAX,Max(dp[i][0],dp[i][1]));
    			}
    			ans += MAX-INF*tt;
    		}
    		else dfs2(i),ans += Max(dp[i][0],dp[i][1]);
    	}
    	Put(ans,'\n');
    	return 0;
    }
    
  • 相关阅读:
    swift优秀学习博客
    Swift主题色顶级解决方案一
    如何用 Swift 语言构建一个自定控件
    自定义UISlider的样式和滑块
    让你提前知道软件开发(27):创建数据库表和索引
    [6] 算法路
    OGG &quot;Loading data from file to Replicat&quot;table静态数据同步配置过程
    一些书籍和下载链接地址读研究生
    悖论软件测试农药
    Maven直接部署Web应用Tomcat
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/15567832.html
Copyright © 2011-2022 走看看