洛谷P1330 封锁阳光大学
P1330 封锁阳光大学
题目描述
曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街。河蟹看到欢快的曹,感到不爽。河蟹决定封锁阳光大学,不让曹刷街。
阳光大学的校园是一张由N个点构成的无向图,N个点之间由M条道路连接。每只河蟹可以对一个点进行封锁,当某个点被封锁后,与这个点相连的道路就被封锁了,曹就无法在与这些道路上刷街了。非常悲剧的一点是,河蟹是一种不和谐的生物,当两只河蟹封锁了相邻的两个点时,他们会发生冲突。
询问:最少需要多少只河蟹,可以封锁所有道路并且不发生冲突。
输入输出格式
输入格式:
第一行:两个整数N,M
接下来M行:每行两个整数A,B,表示点A到点B之间有道路相连。
输出格式:
仅一行:如果河蟹无法封锁所有道路,则输出“Impossible”,否则输出一个整数,表示最少需要多少只河蟹。
输入输出样例
说明
【数据规模】
1<=N<=10000,1<=M<=100000,任意两点之间最多有一条道路。
这个题有思路的话就很水
首先对于每一条边 他的两个端点都必须只有一个有河蟹
那么每一个点都只有有河蟹 和没河蟹两种状态
所以为什么不跑一个DFS?对于图都设定一个起点 然后起点有河蟹跑一次 没河蟹再跑一次 将较小值加进答案 两种都违法就impossible
DFS的具体定义是 对于每一个起点 向每个跟他联通的没访问的节点进行访问并设定成跟起点不一样的状态
如果访问过了就判断是否跟起点状态不同 若否则不合法
最后 图不一定联通
注意一下就可以AC了
代码:
#include<bits/stdc++.h> #define INF 1000000000 using namespace std; int n,m,tra1,tra2; int sum[2]; struct Edge{ int to,nxt; }edge[200010]; int head[10010],ectr,ans,color[10010]; void addedge(int u,int v){ ectr++; edge[ectr].to=v; edge[ectr].nxt=head[u]; head[u]=ectr; } bool vis[10010]; queue<int> q; bool bfs(int start_point,int start_color){ vis[ start_point ] = true; color[ start_point ] = start_color; sum [ start_color ] ++; q.push( start_point ); while(!q.empty()){ int u=q.front(); q.pop(); int nxc=(color[u]+1)%2; for(int i=head[u];i;i=edge[i].nxt){ int v=edge[i].to; if(vis[v]==true){ if(color[v] != nxc) return false; else continue; } color[v]=nxc; vis[v]=true; sum[nxc]++; q.push(v); } } return true; } int main(){ cin>>n>>m; for(int i=1;i<=m;i++){ scanf("%d%d",&tra1,&tra2); addedge(tra1,tra2); addedge(tra2,tra1); } for(int i=1;i<=n;i++){ if(vis[i]==true) continue ; sum[0]=sum[1]=0; if(!bfs(i,0)) { cout<<"Impossible"; return 0; } ans+=min(sum[0],sum[1]); } cout<<ans<<endl; return 0; }
TAG : SIN_XIII ⑨