链接: http://acm.hdu.edu.cn/showproblem.php?pid=4781
题意: 现在给你n个点 m条边,你要构造出来一个有向图,有向图的边权各不相同,从1到m 。并且要求从一个点到其他所有点都是联通的,还要求从一个点出发,回到该点走的路径权值一定要是3的倍数,并且任意两点之间最多只能有一条边,
思路: 题意读懂就是水题。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int ,int > pii;
const int N =100;
int n,m;
int vis[N][N];
int dis[N][N];
int sum[N];
vector<pii>ve[5];
int main()
{
int T;
cin>>T;
int kk=0;
while(T--)
{
scanf("%d %d",&n,&m);
int res=0;
printf("Case #%d:\n",++kk);
for(int i=1; i<=n-1; i++) res+=i;
for(int i=1; i<n; i++)
{
printf("%d %d %d\n",i,i+1,i);
}
int num;
for(int i=n; i<=m; i++)
{
if((res+i)%3==0)
{
num=i;
break;
}
}
printf("%d %d %d\n",n,1,num);
res+=num;
memset(dis,0,sizeof(dis));
memset(sum,0,sizeof(sum));
memset(vis,0,sizeof(vis));
for(int i=2;i<=n;i++){
sum[i]=i-1;
}
for(int i=1;i<=n;i++) sum[i]=sum[i-1]+sum[i];
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
dis[i][j]=sum[j]-sum[i];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<i;j++){
dis[i][j]=res-dis[j][i];
}
}
for(int i=1;i<=n;i++){
vis[i][i]=vis[i][i+1]=1;
}
vis[n][1]=1;
vis[1][n]=1;
for(int i=0;i<=3;i++) ve[i].clear();
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(vis[i][j]) continue;
//cout<<"i "<<i<<" j "<<j<<endl;
int mm=dis[i][j]%3;
ve[mm].push_back(pii(i,j));
}
}
int p1=0;
int p2=0;
int p3=0;
//cout<<"num "<<num<<endl;
for(int i=n;i<=m;i++){
if(i==num) continue;
int mm=i%3;
if(mm==0){
printf("%d %d %d\n",ve[0][p1].first,ve[0][p1].second,i);
p1++;
}
else if(mm==1){
printf("%d %d %d\n",ve[1][p2].first,ve[1][p2].second,i);
p2++;
}
else if(mm==2){
printf("%d %d %d\n",ve[2][p3].first,ve[2][p3].second,i);
p3++;
}
}
}
return 0;
}