给一个数k,让构造出一个节点数小于1000的图,使得这个图上从1到2的最短路的路径数恰好为k.
当天做的时候直接想到分解质因数去做,但这么做对大质数无解=然后就被cha掉了...今天在网上看到一个神奇的做法...
原帖在这:http://7-sun.com/text/25918.html
举个例子
1
3 4 5
6 7 8
9 10 11
2
除了起点终点,每一层三个节点,3和6,7连边,4和6,7连边,然后6和9,10连边,7和9,10连边,然后5--8--11连边得到初始的图。然后1--5,11--2连接,把k分解成二进制表示形式,这样从上到下每一层分别对应k从高位到低位的每一位,比如若最高位为1,那么5和6,7连边,否则不变。然后检测每一位的01状态,到最低位的时候,若最低位为1,就把9--2,,10--2也连上,这样就是最终的结果了。这么做,最多只会用到不到100个点...
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long ll;
bool g[200][200];
int bi[100];
int ct;
int n,m,p,q,k;
void init()
{
int x=3,y=4,z=5;
int nx=6,ny=7,nz=8;
for (int i=1; i<=30; i++)
{
g[x][nx]=g[x][ny]=true;
g[y][nx]=g[y][ny]=true;
g[z][nz]=true;
x=nx; y=ny; z=nz;
nx+=3;ny+=3; nz+=3;
}
g[1][5]=true;
}
int main()
{
init();
cin>>k;
ct=0;
while (k)
{
bi[ct++]=(k&1);
k>>=1;
}
int j=0;
for (int i=ct-1; i>0; i--,j+=3)
{
if (bi[i])
{
g[5+j][5+j+1]=true;
g[5+j][5+j+2]=true;
}
}
j-=3;
g[5+j+1][2]=true;
g[5+j+2][2]=true;
if (bi[0]) g[5+j+3][2]=true;
int nn=5+j+3;
cout<<nn<<endl;
for (int i=1; i<=nn; i++)
{
for (int j=1; j<=nn; j++)
if (g[i][j] || g[j][i]) cout<<"Y";
else cout<<"N";
cout<<endl;
}
return 0;
}