zoukankan      html  css  js  c++  java
  • 【五校联考7day2】QYQ的图

    Description
    给你一个n个点,m条边的无向图,每个点有一个非负的权值ci,现在你需要选择一些点,使得每一个点都满足:
    如果这个点没有被选择,则与它有边相连的所有点都必须被选择。
    问:满足上述条件的点集中,所有选择的点的权值和最小是多少?
    QYQ很快就解决了这个问题,但是他已经回到了左下角……没有留下答案,现在只好请你来解决这个问题啦!

    Input
    从文件graph.in中输入数据。
    输入的第一行包含两个整数n,m
    输入的第二行包含n个整数,其中第i个整数代表ci
    输入的第三行到第m+2行,每行包含两个整数u,v,代表点u和点v之间有一条边

    Output
    输出到文件graph.out中。
    输出的第一行包含一个整数,代表最小的权值和

    Sample Input
    3 1
    1 2 3
    3 1

    Sample Output
    1
    样例说明:
    只选择1号点,满足题意

    Data Constraint
    对于20% 的数据:n<=10
    对于40%的数据:n<=20
    对于100%的数据:1<=n<=50, 1<=m<=500, 0<=c<=1000
    图中可能会有重边,自环。
    点的编号为1—n。

    .
    .
    .
    .
    .
    分许
    直接搜索就好了,当然不要 O(2^n)那种,每次搜索的时候如果这
    个点不选,就直接把与它相连的所有点选上,搜索的时候加入一些剪
    枝,比如如果现在的结果已经比现在的最佳答案大了就直接不搜了。

    .
    .
    .
    .
    .
    .
    程序:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    int n,m,c[51],cnt=1,head[51],ans=2147483647,f[51];
    
    struct edge
    {
    	int next,to;
    } a[1010];
    
    inline int read()
    {
    	int d=0;
    	char ch=getchar();
    	while (ch<'0'||ch>'9') ch=getchar();
    	while (ch>='0'&&ch<='9')
    		d=(d<<3)+(d<<1)+ch-48,ch=getchar();
    	return d;
    }
    
    
    void add(int x,int y)
    {
    	a[cnt].next=head[x];
    	a[cnt].to=y;
    	head[x]=cnt++;
    }
    
    void dfs(int x,int sum)
    {
    	if (sum>=ans) return;
    	if (x>n)
    	{
    		ans=min(ans,sum);
    		return;
    	}
    	f[x]++;
    	dfs(x+1,sum+c[x]);
    	f[x]--;
    	if (!f[x])
    	{
    		for (register int i=head[x];i;i=a[i].next)
    			f[a[i].to]++;
    		dfs(x+1,sum);
    		for (register int i=head[x];i;i=a[i].next)
    			f[a[i].to]--;
    	}
    }
    
    int main()
    {
    	freopen("graph.in","r",stdin);
    	freopen("graph.out","w",stdout);
    	n=read();m=read();
    	for (register int i=1;i<=n;i++)
    		c[i]=read();
    	for (register int i=1;i<=m;i++)
    	{
    		int x,y;
    		x=read();y=read();
    		if (x==y) f[x]++; else
    		{
    			add(x,y);
    			add(y,x);
    		}
    	}
    	dfs(1,0);
    	printf("%d",ans);
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    iOS深入学习(Block全面分析)
    iOS 多快好省的宏定义
    1.ARC和非ARC文件共存
    简单的实现UIpicker上面的取消确定按钮
    ios 简单的倒计时验证码数秒过程实现
    jquerymobile 基础教程
    得到UIView中某个非子视图在UIView中的位置
    状态栏问题
    html表格,列表
    html简单样式
  • 原文地址:https://www.cnblogs.com/YYC-0304/p/10458929.html
Copyright © 2011-2022 走看看