HDU 5637 Transform 单源最短路
2016-05-30 13:12
399 查看
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5637题意:
http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=675&pid=1003题解:
令n=(1<<17)-1。首先很容易想到建图,跑最短路,不过有多次查询,如果每次都跑最短路的话要m*n*logn,会t。
所以可能是我们模型建的太一般化了,需要考虑题目的特殊性。
s到t的最少变化次数本质上等于0到s^t的最少变化次数。
所以我们只要求一次单源最短路径就可以了,只要nlogn的复杂度。
#pragma comment(linker, "/STACK:102400000,102400000") #include<cstdio> #include<cstring> #include<vector> #include<algorithm> #include<queue> using namespace std; const int maxn = 1 << 17; const int mod = 1e9 + 7; const int INF = 1e9; typedef long long LL; vector<int> G[maxn]; int arr[22]; int n, m; int inq[maxn], d[maxn]; void spfa() { queue<int> Q; memset(inq, 0, sizeof(inq)); memset(d, 0x7f, sizeof(d)); d[0] = 0, inq[0] = 1, Q.push(0); while (!Q.empty()) { int u = Q.front(); Q.pop(); inq[u] = 0; for (int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if (d[v] > d[u] + 1) { d[v] = d[u] + 1; if (!inq[v]) { inq[v] = 1; Q.push(v); } } } } } void init() { for (int i = 0; i < maxn; i++) G[i].clear(); } int main() { int tc; scanf("%d", &tc); while (tc--) { scanf("%d%d", &n, &m); init(); for (int i = 0; i < n; i++) scanf("%d", arr + i); for (int i = 0; i < maxn; i++) { for (int j = 0; j < n; j++) { G[i].push_back(i^arr[j]); } for (int j = 0; j < 17; j++) { G[i].push_back(i ^ (1 << j)); } } spfa(); LL ans = 0; for (int i = 1; i <= m; i++) { int u, v; scanf("%d%d", &u, &v); ans += (LL)i*d[u^v]; ans%=mod; } printf("%lld\n", ans); } return 0; }
相关文章推荐
- Hibernate关联映射-一对一(主外键,单双方向)
- js 实现banner轮播
- 解决ViewPager嵌套ViewPager滑动冲突问题
- 加油
- Bitnami LNMP集成包安装简单总结
- nsimage 转 png ,jpg的nsdata 类型
- soj1171 The Game of Efil
- JSP内置对象-out对象
- 1010. 一元多项式求导 (25)
- Springmvc 拦截器
- 如何编写让别人能读懂的代码?
- MySQL远程连接不上的解决
- 开始:COM研究学习
- Git和SVN的区别
- cron表达式详解
- Unity笔记
- mybatis 注解
- iOS Xcode报错exc_bad access code=exc_1386_gpflt处理
- 项目2——动物这样叫1
- CodeForces 624A Save Luke