Codeforces1627 C Not Assigning(dfs,思维)

传送门

思路:

首先,要满足单条边的权值以及相邻两条边的权值和都为质数,这一定得是一个链表,我们找到链的端点,依次赋值2,3即可

刚开始tle了,后来发现是初始化耗时太长
在这里插入图片描述
tle的初始化部分:

void init(){
    cin>>n;
    ff(i,1,n)v[i].clear();
    //对vis和ans不能用clear
    fill(vis.begin(),vis.end(),0);
    fill(ans.begin(),ans.end(),0);
}

修改后的初始化部分:

void init(){
    cin>>n;
    ff(i,1,n)v[i].clear();
    for(int i=1;i<=n;i++)vis[i]=0;
    for(int i=1;i<=n;i++)ans[i]=0;
}

完整ac代码:

#include <bits/stdc++.h>
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define debug(x) cout<<#x<<":"<<x<<endl;
#define f(i,a,n) for(int i=a;i<n;++i)
#define ff(i,a,n) for(int i=a;i<=n;++i)
#define IN freopen("E:\\信竞\\信竞文件夹\\in_c.TXT","r",stdin);
const int INF=0x3f3f3f3f;
using namespace std;
typedef long long ll;
//
const int N=1e5+5;
int n;

struct edge{
    int e,idx;
};

vector<bool> vis(N+1,0);
vector<int> ans(N+1,0);
vector<edge> v[N];

void init(){
    cin>>n;
    ff(i,1,n)v[i].clear();
    for(int i=1;i<=n;i++)vis[i]=0;
    for(int i=1;i<=n;i++)ans[i]=0;
}

void dfs(int x,int w){
    if(!vis[x]){
        vis[x]=1;
        for(int i=0;i<v[x].size();i++){
            if(!vis[v[x][i].e]){
                ans[v[x][i].idx]=w;
                //w^1 : 2->3 , 3->2
                dfs(v[x][i].e,w^1);
            }
        }
    }
}

int main(){
	//IN
    int t;
    cin>>t;
    while(t--){
        init();
        ff(i,1,n-1){
            int x,y;
            cin>>x>>y;
            v[x].push_back({y,i});
            v[y].push_back({x,i});
        }
        int flag=1;
        int p=0;
        ff(i,1,n){
            flag &= (v[i].size()<=2);
            
            //找出链的一个端点位置
            p = (v[i].size() == 1 ? i : p);
        }
        if(!flag)cout<<"-1"<<endl;
        else {
            dfs(p, 2);
            ff(i,1,n-1)cout<<ans[i]<<" ";
            cout<<endl;
        }
    }
}

除了用vector存图,也可以用前向星,此时用 id[i] 存这个边读入时的编号,也可以在dfs里面改变边权,这样dfs的初始点就可以任意了

代码:

#include <bits/stdc++.h>
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define debug(x) cout<<#x<<":"<<x<<endl;
#define f(i,a,n) for(int i=a;i<n;++i)
#define ff(i,a,n) for(int i=a;i<=n;++i)
#define IN freopen("E:\\信竞\\信竞文件夹\\in_c.TXT","r",stdin);
const int INF=0x3f3f3f3f;
using namespace std;
typedef long long ll;
//注意边数需要是点数2倍
const int N=2e5+10;
int h[N],ne[N],e[N],id[N],idx;
int ans[N];
int cnt[N];
bool vis[N];
void add(int a,int b,int c){
    id[idx]=c;
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u,int x){
    vis[u]=true;
    for(int i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        if(!vis[j]){
            ans[id[i]]=x;
            dfs(j,5-x);
			//实现dfs初始点任意
            x=5-x;
        }
    }
}
int main(){
    int t;
    cin>>t;
    while(t--){
        idx=0;
        int n;
        cin>>n;
        ff(i,1,n){
            //防止卡memset
            h[i]=-1;
            cnt[i]=0;
            vis[i]=0;
        }

        int flag=0;
        ff(i,1,n-1){
            int a,b;
            cin >> a >> b;
            add(a, b, i);add(b, a, i);
            cnt[a]++,cnt[b]++;
            if(cnt[a] > 2 || cnt[b] > 2)
                flag=1;
        }
        if(flag)
            cout<<-1<<endl;
        else{
            dfs(1,2);
            f(i,1,n)
                cout<<ans[i]<<" ";
            cout<<endl;
        }
    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值