有一张 n 个点的完全无向图,点的标号是 1...n,其中边 (i,j) 的长度是 i xor j,现在你需要求出点 1 到点 n
的最短路的长度。
Input
第一行一个正整数 T
表示数据组数 1≤T≤100
对于每组数据:第一行一个正整数 n 表示点数 (2≤n≤105)
Output
输出 T
行,每行一个整数表示点 1 到点 n
的最短路
Sample Input
1
3
Sample Output
2
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 100000+10;
const int INF = 1<<30;
struct node
{
int v,dis;
//设置优先队列的优先级,从小到大
bool friend operator < (node n1,node n2)
{
return n1.dis > n2.dis;
}
};
//保存每个点到所有其它与其相连的点
vector<node> adj[maxn];
priority_queue<node> q;
bool vis[maxn];
int dis[maxn];
int n;
//spfa算法
void dijkstra(int s)
{
dis[s] = 0;
node temp;
temp.v = s;
temp.dis = 0;
q.push(temp);
while(!q.empty())
{
node now = q.top();
q.pop();
if(!vis[now.v])
{
vis[now.v] = 1;
for(int i = 1;i <= adj[now.v].size();++i)
{
if(!vis[i] && dis[now.v]+i^now.v < dis[i])
{
dis[i] = dis[now.v]+i^now.v;
node temp;
temp.v = i;
temp.dis = dis[i];
q.push(temp);
}
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i = 0;i <= n;++i)
dis[i] = INF;
for(int i = 0;i <= n;++i)
adj[i].clear();
memset(vis,0,sizeof(vis));
//把1相连的边都比一遍
for(int i = 2;i <= n;++i)
{
dis[i] = i^1;
}
//貌似不需要用最短路算法
//dijkstra(1);
printf("%d\n",dis[n]);
}
return 0;
}