Codeforces Round #617 (Div. 3), problem: (F) Berland Beauty【dfs+贪心】

题意

给你一个n个点的树,树有边权

现在有m个限制条件,表示点u到点v路径上的最小值是w
(注意是路径上的最小值,看了好久的题,比如1到3路径最小值是3 假如2到3为3,但是1到2可以为5 满足1到3路径最小值为3! ) 这句话理解清楚了这个题就不是很难了

现在让我们构造这个树的边权,如果不能构造输出-1

思路

因为n只有5000,所以对于每一个限制条件,我们都在路径上保存一下这条边的最大边权,然后我们记录一下这个限制条件中路径上经过的边的编号

最后再check一遍m次限制路径上的边权的最小值是否等于w即可

code

#include<bits/stdc++.h>
#define mst(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define endl '\n'
using namespace std;
const int maxn=2e5+5;
int n,m,cnt;
int head[maxn];
struct node{
int v,nex,w;
}e[maxn<<1];
void add_edge(int u,int v,int w){
    e[cnt].v=v;
    e[cnt].w=w;
    e[cnt].nex=head[u];
    head[u]=cnt++;
}
int to[maxn],lim[maxn];
int ans[maxn];
vector<int> G[maxn];
void init(){
    mst(head,-1);
    cnt=0;
    for(int i=0;i<=n;i++) G[i].clear();
}
bool dfs(int u,int fa,int id){
    if(u==to[id])return true;
    for(int i=head[u];~i;i=e[i].nex){
        int v=e[i].v;
        if(v==fa) continue;
        if(dfs(v,u,id)){
            int ev=e[i].w;
            ans[ev]=max(ans[ev],lim[id]);
            G[id].push_back(ev);
            return true;
        }
    }
    return false;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    init();
    for(int i=1;i<=n-1;i++){
        int u,v;
        cin>>u>>v;
        add_edge(u,v,i);
        add_edge(v,u,i);
    }
    cin>>m;
    for(int i=1;i<=m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        to[i]=v,lim[i]=w;
        dfs(u,-1,i);
    }
    int flag=1;
    for(int i=1;i<=m&&flag;i++){
        int mmin=inf;
        for(auto it:G[i])
            mmin=min(mmin,ans[it]);
        if(mmin!=lim[i])
            flag=0;
    }
    if(!flag) cout<<-1<<endl;
    else{
        for(int i=1;i<n;i++)
            cout<<max(1,ans[i])<<" ";
        cout<<endl;
    }
    return 0;
}
学如逆水行舟,不进则退
发布了491 篇原创文章 · 获赞 1203 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/weixin_42429718/article/details/104199284