您的位置:首页 > 其它

HDU 4781(图上的构造)

2015-08-25 08:27 281 查看
本题的两个条件:

首先,构造一个图,共有m条边,边权为1 - m互不相同。

图上任意两点间最多有一条有向边,

其次,任意一点经过任意路径回到该点的权值和对3取余为0。

分析:

首先构造一个n个边的有向环,1->2->3...->n->1 ,前n-1条边的权值为1->(n-1),而第n条边为(n,n+1,或者n+2)使得sum%3=0;

那么,这个有向环是符合题意的,只是一些边权为特定值的边还未添加,那么只需在图上找到 dis(i,j)%3 == x%3,那么便可以添加。

#include <cstring>
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <cmath>
#include <vector>
#include <queue>
using namespace std;
#define rep(i,n) for(int i=0;i<int(n);i++)
#define rep1(i,x,y) for(int i=x;i<=(int)y;i++)
typedef long long ll;
const int N = 85;
int n,m,vis

,val

,ans

,hav[N*N];
int cal(int x){
   rep1(i,1,n)rep1(j,1,n)if(i!=j){
       if(vis[i][j] || vis[j][i] ) continue;
       if(val[i][j] % 3 == x % 3){
           ans[i][j]=x;
           hav[x] = 1;
           vis[i][j]=1;
           return 1;
       }
   }
   return 0;
}
struct node{
   int to,v;
   node(int to=0,int v=0):to(to),v(v){}
};
vector<node> G
;
int dis(int s,int t,int fa,int now){
   if(s == t) return now;
   rep(i,G[s].size())if(G[s][i].to!=fa){
        return dis(G[s][i].to,t,s,now+G[s][i].v);
   }
}
int init(){
   for(int i=1;i<=n;i++) G[i].clear();
   memset(vis,0,sizeof(vis));
   memset(hav,0,sizeof(hav));
   int sum = 0;
   for(int i=1;i<=n-1;i++){
      int x = i, y=i+1;
      vis[x][y] = 1;
      ans[x][y] = i;
      G[x].push_back(node(y,i));
      sum+=i;
      hav[i]=1;
   }
   for(int i=n;i<=m;i++){
       if((sum+i)% 3== 0){
           hav[i] = 1;
           vis
[1] = 1;
           ans
[1] = i;
           G
.push_back(node(1,i));
           break;
       }
   }
   for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)
      if(i!=j) val[i][j] = dis(i,j,-1,0);
   for(int i=1;i<=m;i++)if(!hav[i]){
       if(!cal(i)) return 0;
   }
   return 1;
}
int main()
{
    int T,kase=1;
    scanf("%d",&T);
    while(T--){
       scanf("%d %d",&n,&m);
       printf("Case #%d:\n",kase++);
       if(init()){
           rep1(i,1,n) rep1(j,1,n){
               if(vis[i][j]) {
                   printf("%d %d %d\n",i,j,ans[i][j]);
               }
           }
       }
       else printf("-1\n");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: