Assignment For Princess HDU - 4781

http://acm.hdu.edu.cn/showproblem.php?pid=4781

先构造一个权值模3为0的大圈 平方预处理一下所有弧(共n*(n-1)/2条弧) 然后用剩下的边来和圈上的某个弧来凑成权值模3为0的小圈 这样不会破坏已经构造好的圈 并且一次只消耗一条弧

#include <bits/stdc++.h>
using namespace std;
#define pii pair <int,int>

struct node
{
    int u;
    int v;
    int w;
};

pii v[3][10000];
node edge[10010];
int e[100][100];
int dis[100][100];
int sz[3];
int n,m;

void init()
{
    int i,j,k;
    memset(dis,0,sizeof(dis));
    for(i=0;i<n;i++)
    {
        for(j=0,k=i;j<n-1;j++,k=(k+1)%n)
        {
            dis[i][edge[k].v]=dis[i][edge[k].u]+edge[k].w;
        }
    }
    sz[0]=0,sz[1]=0,sz[2]=0;
    for(i=0;i<n;i++)
    {
        for(j=0,k=(i+2)%n;j<n-3;j++,k=(k+1)%n)
        {
            if(dis[i][k]%3==0) v[0][sz[0]++]=make_pair(k,i);
            else if(dis[i][k]%3==1) v[2][sz[2]++]=make_pair(k,i);
            else v[1][sz[1]++]=make_pair(k,i);
        }
    }
}

int main()
{
    pii tmp;
    int t,cas,i,flag;
    scanf("%d",&t);
    for(cas=1;cas<=t;cas++)
    {
        scanf("%d%d",&n,&m);
        memset(e,0,sizeof(e));
        for(i=0;i<m;i++) edge[i].w=i+1;
        if(n%3==1) swap(edge[n-1].w,edge[n+1].w);
        for(i=0;i<n;i++)
        {
            e[i][(i+1)%n]=1;
            e[(i+1)%n][i]=1;
            edge[i].u=i,edge[i].v=(i+1)%n;
        }
        init();
        flag=1;
        for(i=n;i<m;i++)
        {
            if(sz[edge[i].w%3]>0)
            {
                flag=0;
                while(sz[edge[i].w%3]>0)
                {
                    sz[edge[i].w%3]--;
                    tmp=v[edge[i].w%3][sz[edge[i].w%3]];
                    if(e[tmp.first][tmp.second]==0)
                    {
                        e[tmp.first][tmp.second]=1;
                        e[tmp.second][tmp.first]=1;
                        edge[i].u=tmp.first,edge[i].v=tmp.second;
                        flag=1;
                        break;
                    }
                }
            }
            else
            {
                flag=0;
                break;
            }
        }
        printf("Case #%d:\n",cas);
        if(flag) for(i=0;i<m;i++) printf("%d %d %d\n",edge[i].u+1,edge[i].v+1,edge[i].w);
        else printf("-1\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/82453339