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;
    }
    

      

  • 相关阅读:
    【SCOI 2011】 糖果
    【POJ 3159】 Candies
    【POJ 1716】 Integer Intervals
    【POJ 2983】 Is the information reliable?
    【POJ 1364】 King
    【POJ 1201】 Intervals
    【POJ 1804】 Brainman
    6月10日省中提高组题解
    【POJ 3352】 Road Construction
    【POJ 1144】 Network
  • 原文地址:https://www.cnblogs.com/xuesu/p/4338700.html
Copyright © 2011-2022 走看看