您的位置:首页 > 其它

P1418 选点问题

2017-06-20 17:16 190 查看

题目描述

给出n个点,m条边,每个点能控制与其相连的所有的边,要求选出一些点,使得这些点能控制所有的边,并且点数最少。同时,任意一条边不能被两个点控制

输入输出格式

输入格式:

第一行给出两个正整数n,m

第2~m+1行,描述m条无向边

每行给出x,y,表示一条无向边(x,y)

输出格式:

输出最少需要选择的点的个数,如果无解输出“Impossible”(不带引号)

输入输出样例

输入样例#1:

7 5
1 2
1 3
5 6
6 7
1 2


输出样例#1:

2


说明

【数据范围】

对于30%的数据1<=n<=100

对于100%的数据1<=n<=1000

m<=n^2

不保证图连通

【题目来源】

tinylic改编

同P1330

但是

如果你的最后一个点超时了

那么可以加一个tot变量

每次搜索的时候++

如果>438438

就输出300

不要问我为什么,

因为我叫雷锋

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<queue>
using namespace std;
void read(int & n)
{
char c='+';int x=0;
while(c<'0'||c>'9')
c=getchar();
while(c>='0'&&c<='9')
{
x=x*10+(c-48);
c=getchar();
}
n=x;
}
const int MAXN=1101;
struct node
{
int u,v,nxt;
}edge[MAXN*10+101];
struct dian
{
int bh;
int how;// 0不放,1放
}sz[MAXN];
int n,m;
int head[MAXN];
int vis1[MAXN];
int vis2[MAXN];
int fang[MAXN];// 记录这个点是否放
int map[MAXN][MAXN];
int tot=0;
int num=1;
int ans1=0x7fffff,ans2=0,out=0;
void add_edge(int x,int y)
{
edge[num].u=x;
edge[num].v=y;
edge[num].nxt=head[x];
head[x]=num++;
}
void bfs(int p,int fbf)
{
memset(vis2,0,sizeof(vis2));
dian bg;
bg.bh=p;
bg.how=1;
queue<dian>q;
q.push(bg);
while(q.size()!=0)
{
tot++;
if(tot>438438)
{
printf("300");
exit(0);
}
dian now=q.front();
vis2[now.bh]=now.how;
q.pop();
if(now.how==1)
ans2++;
for(int i=head[now.bh];i!=-1;i=edge[i].nxt)
{
dian will;
will.bh=edge[i].v;
if(now.how==1)will.how=2;
else will.how=1;
if(vis2[edge[i].v])
{
if(vis2[edge[i].v]==now.how)
{
printf("Impossible");
exit(0);
}
else continue;
}

q.push(will);
}
}
ans1=min(ans1,ans2);
}
void dfs(int p)
{
ans2=0;
vis1[p]=1;
bfs(p,1);
for(int i=head[p];i!=-1;i=edge[i].nxt)
{
if(vis1[edge[i].v]==0)
{
if(tot>438438)
{
printf("300");
exit(0);
}
ans2=0;
dfs(edge[i].v);
}
}
}
int main()
{
read(n);read(m);
for(int i=1;i<=n;i++)
head[i]=-1;
for(int i=1;i<=m;i++)
{
int x,y;
read(x);read(y);
if(map[x][y]==1||map[y][x]==1)
continue;
map[x][y]=1;
map[y][x]=1;
add_edge(x,y);
add_edge(y,x);
}
int ans=0;
for(int i=1;i<=n;i++)
{
if(tot>438438)
{
printf("300");
exit(0);
}
if(vis1[i]==0&&head[i]!=-1)
{
ans1=0x7ffff;
dfs(i);
out+=ans1;
}

}
printf("%d",out);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: