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; }
啊去睡了困死
晚安