• P2495 [SDOI2011]消耗战


    在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达。现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战斗,我军胜利在望。已知在其他k个岛屿上有丰富能源,为了防止敌军获取能源,我军的任务是炸毁一些桥梁,使得敌军不能到达任何能源丰富的岛屿。由于不同桥梁的材质和结构不同,所以炸毁不同的桥梁有不同的代价,我军希望在满足目标的同时使得总代价最小。

    侦查部门还发现,敌军有一台神秘机器。即使我军切断所有能源之后,他们也可以用那台机器。机器产生的效果不仅仅会修复所有我军炸毁的桥梁,而且会重新随机资源分布(但可以保证的是,资源不会分布到1号岛屿上)。不过侦查部门还发现了这台机器只能够使用m次,所以我们只需要把每次任务完成即可。

    输入格式

    第一行一个整数n,代表岛屿数量。

    接下来n-1行,每行三个整数u,v,w,代表u号岛屿和v号岛屿由一条代价为c的桥梁直接相连,保证1<=u,v<=n且1<=c<=100000。

    第n+1行,一个整数m,代表敌方机器能使用的次数。

    接下来m行,每行一个整数ki,代表第i次后,有ki个岛屿资源丰富,接下来k个整数h1,h2,…hk,表示资源丰富岛屿的编号。

    输出格式

    输出有m行,分别代表每次任务的最小代价。

    输入输出样例

    输入 #1

    10
    
    1 5 13
    
    1 9 6
    
    2 1 19
    
    2 4 8
    
    2 3 91
    
    5 6 8
    
    7 5 4
    
    7 8 31
    
    10 7 9
    
    3
    
    2 10 6
    
    4 5 7 8 3
    
    3 9 4 6
    

    输出 #1

    12
    
    32
    
    22
    

    说明/提示

    【数据规模和约定】

    对于10%的数据,2<=n<=10,1<=m<=5,1<=ki<=n-1

    对于20%的数据,2<=n<=100,1<=m<=100,1<=ki<=min(10,n-1)

    对于40%的数据,2<=n<=1000,m>=1,sigma(ki)<=500000,1<=ki<=min(15,n-1)

    对于100%的数据,2<=n<=250000,m>=1,sigma(ki)<=500000,1<=ki<=n-1

    这题也是个虚树模板和CF613D Kingdom and its Cities 类似,我的题解link

    建出虚树之后 , 每个点要么弄他 , 要么把他的儿子全弄了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<cstdlib>
    using namespace std;
    const int N = 251000;
    #define int long long
    inline int read()
    {
    	register int x = 0 , f = 0; register char c = getchar();
    	while(c < '0' || c > '9') f |= c == '-' , c = getchar();
    	while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0' , c = getchar();
    	return f ? -x : x;
    }
    #define RQ { puts("RQ"); /*exit(0);*/ }
    int n , cnt , id , top , ans;
    int head[N] , dfn[N] , a[N] , f[N][18] , sta[N] , d[N] , siz[N] , val[N] , dp[N];
    vector<int> ed[N];
    struct edge{int v , nex , c; } e[N<<1];
    inline void add(int u , int v , int c) { e[++cnt].v = v; e[cnt].nex = head[u]; e[cnt].c = c; head[u] = cnt; return ;}
    inline bool cmp(const int &A , const int &B) { return dfn[A] < dfn[B]; }
    inline void addc(int u , int v) { ed[v].push_back(u); return ; }
    
    void dfs(int x , int fa)
    {
    	dfn[x] = ++id; d[x] = d[fa] + 1;
    	for(int i = 1 ; i <= 17 ; ++i) f[x][i] = f[f[x][i-1]][i-1];
    	for(int i = head[x] , v ; i ; i = e[i].nex)
    	{
    		v = e[i].v; if(v == fa) continue; 
    		dp[v] = min(dp[x] , e[i].c);
    		f[v][0] = x; dfs(v , x);
    	}
    	return ;
    }
    
    int LCA(int x , int y)
    {
    	if(x == y) return x;
    	int i; if(d[x] < d[y]) swap(x , y);
    	for(i = 17 ; i >= 0 ; --i) if(d[f[x][i]] >= d[y]) x = f[x][i];
    	if(x == y) return x;
    	for(i = 17 ; i >= 0 ; --i) if(f[x][i] ^ f[y][i]) x = f[x][i] , y = f[y][i];
    	return f[x][0];
    }
    
    void build_tree(int k)
    {
    	sort(a + 1 , a + 1 + k , cmp);
    	top = 0; int i = 1;
    	if(a[1] != 1) sta[top = 1] = 1;
    	for(i = 1 ; i <= k ; ++i)
    	{
    		if(top <= 1) { sta[++top] = a[i]; continue; }
    		int p = LCA(sta[top] , a[i]);
    		if(p == sta[top]) continue;
    		while(top > 1 && d[sta[top-1]] >= d[p]) addc(sta[top] , sta[top-1]) , top--;
    		if(sta[top] != p) addc(sta[top] , p) , sta[top] = p;
    		sta[++top] = a[i];
    	}
    	while(top > 1) addc(sta[top] , sta[top-1]) , top--;
    	return ;
    }
    
    int dfs2(int x)
    {
    	if((int)ed[x].size() == 0) return dp[x];
    	int res = 0;
    	for(int i = 0 , s = ed[x].size(); i < s ; ++i)
    		res += dfs2(ed[x][i]);
    	ed[x].clear();
    	return min(dp[x] , res);
    }
    
    signed main()
    {
    	n = read();
    	for(int i = 1 , a , b , c; i < n ; ++i) 
    	{
    		a = read() , b = read(); c = read();
    		add(a , b , c); add(b , a , c);
    	}
    	memset(dp , 0x3f , sizeof dp); dfs(1 , 0);
    	int m = read();
    	for(int i = 1 , k ; i <= m ; ++i)
    	{
    		k = read();
    		for(int j = 1 ; j <= k ; ++j) a[j] = read();
    		build_tree(k);
    		printf("%lld
    " , dfs2(1));
    	}
    	return 0;
    }
    /*
    10
    1 5 13
    1 9 6
    2 1 19
    2 4 8
    2 3 91
    5 6 8
    7 5 4
    7 8 31
    10 7 9
    3
    2 10 6
    4 5 7 8 3
    3 9 4 6
    */
    
  • 相关阅读:
    JMeter中的HTTPS套接字错误
    使用JMETER进行REST API测试(分步指南)
    JMeter BeanShell示例
    未能载入软件包“WebDriverAgentRunner”,因为它已损坏或丢失必要的资源。
    ERROR: Could not connect to lockdownd, error code -19 -20
    (转)Selenium-11: Execute JavaScript with JavascriptExecutor
    在服务器上使用 gradle 打包 android 源码
    poi+properties文件实现多环境测试数据一键切换
    cocos2D-X 常用功能封装
    MD5 AND JSON AND XML
  • 原文地址:https://www.cnblogs.com/R-Q-R-Q/p/12159426.html
Copyright © 2020-2023  润新知