zoukankan      html  css  js  c++  java
  • URAL 1040 Airline Company 构造,思路 难度:2

    http://acm.timus.ru/problem.aspx?space=1&num=1040

    题目要求在一个联通无向图中找出一种方法给边标号使得任意一个有多条边的点,边的号码的最大公约数都为1

    想象在dfs树上,以1为根进入,将第一条边标为序号1,则节点1满足条件

    剩下的边遵照dfs顺序表明,那么非叶节点一定满足从父亲到自身的树边和自身的另一条边序号相邻

    所以直接dfs标号即可

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn=51;
    const int maxm=maxn*maxn;
    int first[maxn];
    struct edge{
            int f,t,ind,nxt;
    }e[maxm];
    int elen;
    int ind[maxm];
    void addedge(int f,int t,int ind){
            e[elen].f=f;
            e[elen].t=t;
            e[elen].ind=ind;
            e[elen].nxt=first[f];
            first[f]=elen++;
    }
    int n,m,cnt;
    bool vis[maxn];
    void dfs(int s){
            vis[s]=true;
            for(int p=first[s];p!=-1;p=e[p].nxt){
                    if(ind[e[p].ind]==0){
                            ind[e[p].ind]=++cnt;
                            int t=e[p].t;
                            if(!vis[t]){
                                    dfs(t);
                            }
                    }
            }
    }
    int gcd(int a,int b){
            if(a<b)swap(a,b);
            if(b==0)return a;
            return gcd(b,a%b);
    }
    int main(){
            scanf("%d%d",&n,&m);
            memset(first,-1,sizeof(first));
            for(int i=0;i<m;i++){
                    int f,t;
                    scanf("%d%d",&f,&t);
                    addedge(f,t,i);
                    addedge(t,f,i);
            }
            dfs(1);
            for(int i=1;i<=n;i++){
                    int g=-1;
                    int len=0;
                     for(int p=first[i];p!=-1;p=e[p].nxt){
                            len++;
                            if(g==-1){
                                    g=ind[e[p].ind];
                            }
                            else {
                                    g=gcd(g,ind[e[p].ind]);
                            }
                    }
                    if(len>1&&g!=1){
                            puts("NO");
                            return 0;
                    }
            }
            puts("YES");
            for(int i=0;i<m;i++){
                    printf("%d%c",ind[i],i==m-1?'
    ':' ');
            }
            return 0;
    }
    

      

  • 相关阅读:
    windows服务程序
    DevExpress之时间控件
    DevExpress之列表控件
    Docker安装及基本使用
    配置阿里云yum源
    Centos7安装gitlab
    正则表达式
    sed进阶
    初识sed和gawk
    安装saltstack
  • 原文地址:https://www.cnblogs.com/xuesu/p/4338700.html
Copyright © 2011-2022 走看看