luogu P1330 封锁阳光大学

emmmm

下午被dtx大佬强迫(用词似乎不当?)去做

他tql!!!%%%

然鹅最终还是他给我讲的www

所以这其实是一道图的遍历

但是我有搜索恐惧症啊啊啊看到搜索整个人都慌了

 

而且看题面

这道题还有一个仔细想想就能想出来的点

就是每一条边的两个点,一定是一个有河蟹,一个没有的

所以标记一下就比较好判断了

然后要注意这道题它并不只是一个图

所以要把每一次走过的图标记一下,下次不走

这是dtx大佬身先士卒下数据得来的经验orz

然后看一下代码吧

有点晚了太困了所以水一发23333

#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 10010

int color[maxn];
int to[maxn * 20],nxt[maxn * 20],head[maxn * 20];//无向图呦
int cnt;
int flag[maxn];
int ans,orz;

void add(int x,int y){
  nxt[++cnt] = head[x];
  to[cnt] = y;
  head[x] = cnt;
}//存图

int dfs(int qwq,int col){//呀讨厌的dfs
  if(flag[qwq]){
    if(color[qwq] == col)//如果搜过了并且没有问题返回1
      return 1;
    return 0;//互相矛盾了返回0
  }
  flag[qwq] = 1;//标记一下走过了
  if(col == 0)ans++;
  else orz++;//两个都计一下数,最后取最小的(因为放河蟹反过来是一样的都能理解吧
  color[qwq] = col;//把颜色标记一下
  for(int i = head[qwq];i;i = nxt[I])//遍历这个图
    if(!dfs(to[i],1 - col))//不合理返回0
      return 0;
  return 1;
}

int main(){
  int n,m;
  scanf("%d%d",&n,&m);
  for(int i = 1;i <= m;i++){
    int x,y;
    scanf("%d%d",&x,&y);
    add(x,y);
    add(y,x);//双向存图
  }
  int sum = 0;//很多个图最后的总和
  for(int i = 1;i <= n;i++){
    if(flag[I])//这个图遍历过了直接下一次循环
      continue;
    ans = 0,orz = 0;
    if(!dfs(i,0)){
      printf("Impossible");
      return 0;
    }
    sum += min(ans,orz);
  }
  printf("%d",sum);
  return 0;
}

啊去睡了困死

晚安

posted @ 2018-12-10 22:31  ./seven  阅读(168)  评论(1编辑  收藏  举报