HZNU Training 32 for Zhejiang Provincial Competition 2020

B - B

 CodeForces - 723E 

一张无向图,给边指定方向,问最多可以让多少个点度数为0,输出方案。

考虑欧拉回路性质:度数为偶数的点一定可以变成为0,对于度数为奇数的点,将每个点向0连一条边,度数为奇数的点一定有偶数个,

构造一个欧拉回路,直接用set保存输出。dfs删除对应的边。

#include<bits/stdc++.h>
using namespace std;
const int N=8e3+5;
#define pb push_back
int ecnt,n,m;
int degree[N];
set<int>G[N];
vector<int>V;
vector<pair<int,int> >ans;
void init(){
    for(int i=1;i<=n;i++)degree[i]=0;
        V.clear();ans.clear();
}
void dfs(int u){
        while(G[u].size()){
            int v=*G[u].begin();
            ans.pb(make_pair(u,v) );
            G[u].erase(v);G[v].erase(u);
            dfs(v);
        }
}
int main(){
    int t;scanf("%d",&t);
    while(t--){
        scanf("%d %d",&n,&m);
        init();
        for(int i=1,u,v;i<=m;i++){
            scanf("%d %d",&u,&v);
            G[u].insert(v);G[v].insert(u);
            degree[u]++;degree[v]++;
        }
        int cur=0;
        for(int i=1;i<=n;i++){
            if(degree[i]%2==0)cur++;
            else V.pb(i);
        }
        for(int i=0;i<V.size();i++){
            G[0].insert(V[i]);G[V[i]].insert(0);
        }
        for(int i=1;i<=n;i++)dfs(i);
        printf("%d\n",cur);
        for(int i=0;i<ans.size();i++){
        
        if(ans[i].first&&ans[i].second){
            printf("%d %d\n",ans[i].first,ans[i].second);
        }

        }
    }
    // system("pause");
    return 0;
}
View Code

F - F

 HDU - 5413 

题意:DAG问多少个多余的边。

考虑保存每个点的前驱。当枚举到当前边时,如果之前已经有点访问过了,说明当前边是多余的。

用bitset维护,复杂度为O(n*n/32)

#include <bits/stdc++.h>
#include <bitset>
using namespace std;
const int  N=2e4+50;
int n,m;
int in[N];
vector<int>G[N],pre[N],top;
bitset<N>bit[N];
void init(){
    for(int i=1;i<=n;i++)pre[i].clear(),in[i]=0,G[i].clear();
    top.clear();
}
void topo(){
    queue<int>Q;
    for(int i=1;i<=n;i++)if(in[i]==0){Q.push(i);top.push_back(i);}
        while(!Q.empty()){
            int u=Q.front();Q.pop();
            top.push_back(u);
            for(int i=0;i<G[u].size();i++){
                int v=G[u][i];
                if(--in[v]==0)Q.push(v);
                pre[v].push_back(u);
            }
        }
}
int main(){
    int t;scanf("%d",&t);
    while(t--){
        scanf("%d %d",&n,&m);
        init();
        for(int i=1,u,v;i<=m;i++){
            scanf("%d %d",&u,&v);
            G[u].push_back(v);
            in[v]++;
        }
        topo();
        int ans=0;
        for(int i=1;i<=n;i++)bit[i].reset(),bit[i].set(i);
        for(int i=0;i<top.size();i++){
            int u=top[i];
            for(int j=pre[u].size()-1;j>=0;j--){
                int v=pre[u][j];
                if(bit[u][v])ans++;
                bit[u]|=bit[v];
            }
        }
        printf("%d\n",ans);
    }
    // system("pause");
    return 0;
}
View Code
 

猜你喜欢

转载自www.cnblogs.com/littlerita/p/12951581.html
今日推荐