1,acwing 164.可达性统计;2, Decorating the Pastures;3, Perimeter
1,可达性统计;
思路:设f[x]表示x能到达的点的个数,
那么f[x]=(x)||f(y1)||f(y2)||.... (’||‘就是或运算,y1,y2是存在有向边的(x,y1)...);
因此,要求f[x]就要知道后面的f[y1],f[y2]..所以就要按拓扑排序的逆序来做;
在表示x能否到i,可以用状态压缩,但是数据很长不是32位,就用到了bitset;
也就是将状态压缩不局限int来表示,而是可定长度的01数组来表示,并且 支持位运算;
一般来说是bitset<N>f[N],f[i]代表一串01字符(一行),第i位是1就表示能到;
f[i][i]就是本身;
- #pragma GCC optimize(2)
- #include<bits/stdc++.h>
- #define rep1(i,a,n) for( int i=a;i<n;++i)
- #define rep2(i,a,n) for( int i=a;i<=n;++i)
- #define per1(i,n,a) for( int i=n;i>a;i--)
- #define per2(i,n,a) for( int i=n;i>=a;i--)
- #define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
- #define memset(a,i,b) memset((a),(i),sizeof (b))
- #define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
- #define pro_q priority_queue
- #define pb push_back
- #define pf push_front
- #define endl "\n"
- #define lowbit(m) ((-m)&(m))
- #define YES cout<<"YES\n"
- #define NO cout<<"NO\n"
- #define Yes cout<<"Yes\n"
- #define No cout<<"No\n"
- #define yes cout<<"yes\n"
- #define no cout<<"no\n"
- #define yi first
- #define er second
- using namespace std;
- typedef pair<long long,long long>PLL;
- typedef long long LL;
- typedef pair<int,int> PII;
- typedef pair<int,PII> PIII;
- typedef double dob;
- const int N=3e4+10;
- int e[N],ne[N],h[N],idx;
- int d[N];
- void add(int a,int b)
- {
- e[idx]=b,ne[idx]=h[a],h[a]=idx++;
- }
- int n,m;
- vector<int>xl;
- bitset<N>f[N];
- void topsort()
- {
- queue<int>q;
- rep2(i,1,n)if(!d[i])q.push(i);
- while (q.size())
- {
- int t=q.front();
- q.pop();
- xl.pb(t);
- for(int i=h[t];~i;i=ne[i])
- {
- int j=e[i];
- if(--d[j]==0)
- {
- q.push(j);
- }
- }
- }
-
- }
- signed main()
- {
- quick_cin();
- cin>>n>>m;
- memset(h,-1,h);
- while(m--)
- {
- int a,b;
- cin>>a>>b;
- add(a,b);
- d[b]++;
- }
- topsort();
- per2(i,n-1,0)
- {
- int j=xl[i];
- f[j][j]=1;
- for(int k=h[j];~k;k=ne[k])
- {
- f[j]|=f[e[k]];
- }
- }
- rep2(i,1,n)cout<<f[i].count()<<endl;
- return 0;
- }
2, Decorating the Pastures
题意:
n个牧场,m条双向道路连接,现给每个牧场插旗,有F和J两种,规定一条道路连接的两个牧场不能插同一种,求J最大的数,如果没有输出-1;
思路:不知道有没有孤立点,就遍历每个牧场,遍历过的标记,然后开始插旗,差的时候下一层和父亲不能一样,判断没有方案就是父亲和孩子插的旗一样;
- #pragma GCC optimize(2)
- #include<bits/stdc++.h>
- #define rep1(i,a,n) for( int i=a;i<n;++i)
- #define rep2(i,a,n) for( int i=a;i<=n;++i)
- #define per1(i,n,a) for( int i=n;i>a;i--)
- #define per2(i,n,a) for( int i=n;i>=a;i--)
- #define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
- #define memset(a,i,b) memset((a),(i),sizeof (b))
- #define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
- #define pro_q priority_queue
- #define pb push_back
- #define pf push_front
- #define endl "\n"
- #define lowbit(m) ((-m)&(m))
- #define YES cout<<"YES\n"
- #define NO cout<<"NO\n"
- #define Yes cout<<"Yes\n"
- #define No cout<<"No\n"
- #define yes cout<<"yes\n"
- #define no cout<<"no\n"
- #define yi first
- #define er second
- #define INF 0x3f3f3f3f
- using namespace std;
- typedef pair<int,int> PII;
- typedef pair<long long,long long>PLL;
- typedef pair<int,PII> PIII;
- typedef long long LL;
- typedef double dob;
- int n,m;
- const int N=1e6+10;
- int e[N],ne[N],h[N],idx;
- void add(int a,int b)
- {
- e[idx]=b,ne[idx]=h[a],h[a]=idx++;
- }
- int numj1,numj2;
- int st[N];
- bool ispf=0;
- void bfs1(int x)
- {
- queue<int>q;
- q.push(x);
- st[x]=1;
- numj1++;
- int f=1;
- while(q.size())
- {
- int t=q.front();
- q.pop();
- for(int i=h[t];~i;i=ne[i])
- {
- int j=e[i];
- if(!st[j])
- {
- q.push(j);
- if(st[t]==1)st[j]=2,numj2++;
- if(st[t]==2)st[j]=1,numj1++;
- }
- else
- {
- if(st[j]==st[t])
- {
- ispf=1;
- return;
- }
- }
- }
- }
- }
- int ans;
- signed main()
- {
- quick_cin();
- memset(h,-1,h);
- cin>>n>>m;
- while(m--)
- {
- int a,b;
- cin>>a>>b;
- add(a,b),add(b,a);
- }
-
- rep2(i,1,n)
- {
- if(!st[i])
- {
- numj1=0,numj2=0;
- bfs1(i);
- if(ispf)
- {
- cout<<-1;
- return 0;
- }
- ans+=max(numj1,numj2);
- }
- }
- cout<<ans;
- return 0;
- }
3, Perimeter
dfs搜索最外边周长;
注意set的用法;
- #pragma GCC optimize(2)
- #include<bits/stdc++.h>
- #define rep1(i,a,n) for( int i=a;i<n;++i)
- #define rep2(i,a,n) for( int i=a;i<=n;++i)
- #define per1(i,n,a) for( int i=n;i>a;i--)
- #define per2(i,n,a) for( int i=n;i>=a;i--)
- #define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
- #define memset(a,i,b) memset((a),(i),sizeof (b))
- #define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
- #define pro_q priority_queue
- #define pb push_back
- #define pf push_front
- #define endl "\n"
- #define lowbit(m) ((-m)&(m))
- #define YES cout<<"YES\n"
- #define NO cout<<"NO\n"
- #define Yes cout<<"Yes\n"
- #define No cout<<"No\n"
- #define yes cout<<"yes\n"
- #define no cout<<"no\n"
- #define yi first
- #define er second
- using namespace std;
- typedef pair<long long,long long>PLL;
- typedef long long LL;
- typedef pair<int,int> PII;
- typedef pair<int,PII> PIII;
- typedef double dob;
- set<PII>s,vis;
- int n;
- int ans;
- bool ishole(int x,int y)
- {
- rep2(i,-1,1)
- rep2(j,-1,1)
- {
- if(s.count(make_pair(x+i,y+j))==1)return 0;
- }
- return 1;
- }
- int dx[]={-1,0,1,0};
- int dy[]={0,1,0,-1};
- void dfs(int x,int y)
- {
- if(s.count(make_pair(x,y)))
- {
- ans++;
- return;
- }
- if(vis.count(make_pair(x,y)))return;
- vis.insert(make_pair(x,y));
- if(ishole(x,y))return;
- rep1(i,0,4)
- {
- dfs(x+dx[i],y+dy[i]);
- }
- }
- signed main()
- {
- quick_cin();
- cin>>n;
- while (n--)
- {
- int x,y;
- cin>>x>>y;
- s.insert(make_pair(x,y));
- }
- auto st=*s.begin();
- dfs(st.first-1,st.second-1);
- cout<<ans;
-
- return 0;
- }