您的位置:首页 > 其它

哈尔滨2013校赛训练赛 4 解题思路

2013-03-19 21:12 351 查看
A.跑步

  二分枚举距离,然后构图用并查集判联通数量是否大与等于N,时间复杂度是 Nlog(N),

因为所给坐标较大,注意求解距离时强制转换,防止溢出~

View Code

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;

const int N = 5010;
const int M = 100010;
const int INF = 0x3fffffff;

vector< pair<int,int> > edge
;
int S, T, K;
int n, m;
int dis
[510];
bool vis
;

queue<int> Q;

void spfa(){
while(!Q.empty()) Q.pop();

for(int i = 1; i <= n; i++ ){
vis[i] = 0;
for(int j = 0; j <= K; j++)
dis[i][j] = INF;
}
dis[S][0] = 0;
Q.push( S );
vis[S] = 1;
while( !Q.empty() ){
int u = Q.front(); Q.pop();
vis[u] = 0;
for(int i = 0; i < edge[u].size(); i++){
int v = edge[u][i].first, cost = edge[u][i].second;
for(int j = 1; j <= K; j++){
if( dis[v][j] > dis[u][j-1]+cost ){
dis[v][j] = dis[u][j-1]+cost;
if( !vis[v] ) Q.push(v), vis[v] = 1;
}
if(  (j==K) && (dis[v][j] > dis[u][j]+cost) ){
dis[v][j] = dis[u][j]+cost;
if( !vis[v] ) Q.push(v), vis[v] = 1;
}
}
}
}
}

int main(){

int T;
scanf("%d", &T);
while( T-- ){
scanf("%d%d", &n, &m);
int a, b, c;
for(int i = 1; i <= n; i++) edge[i].clear();
for(int i = 0; i < m; i++){
scanf("%d%d%d", &a,&b,&c);
edge[a].push_back( make_pair(b,c) );
edge[b].push_back( make_pair(a,c) );
}
scanf("%d%d%d", &S,&T,&K);
K = (K+9)/10;
spfa();
if( dis[T][K] == INF ) puts("-1");
else    printf("%d\n", dis[T][K] );
}
return 0;
}


J 数论中的异或

  若我们只考虑二进制表示,则每个数只有30位,对于异或操作,只能得出 1,0. 1,0的总数是对应的,

所以我们可以通过每个位置0,1数量来判定当前位置应该为0,还是1,然后化成10进制即可。    
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: