SGU 145
节点不可重复经过的K短路问题。
思路:二分路径长度,深搜小于等于路径长度的路径数。可以利用可重复点K短路问题中的A*函数进行剪枝。
尝试另一种解法:把可重复点K短路A*直接搬过来,堆中的每个元素额外记录之前走过的所有点。这样就可以据此防止走重复的点。最大100个点,可用两个长整形状态压缩。
一直PE,无法验证效率。
#include <map>
#include <set>
#include <list>
#include <queue>
#include <stack>
#include <cmath>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll; #define eps 1e-8
#define inf 0x7f3f3f3f
#define debug puts("BUG")
#define read freopen("in.txt","r",stdin) #define N 111
#define M 11111
struct node
{
int v,w,n;
}ed[M],ed2[M];
int head[N],head2[N],cnt,cnt2;
struct str
{
int v,p;
}st[M*];
struct node2
{
int v,g,f,dx;
ll m1,m2;
void set(int _v,int _g,int _f,int dx,ll m1,ll m2)
{
this->v = _v;
this->g = _g;
this->f = _f;
this->dx = dx;
this->m1 = m1;
this->m2 = m2;
}
bool operator < (const node2 &n) const
{
if (n.f == f) return n.g < g;
return n.f < f;
}
};
void sc(int s,ll &m1,ll &m2)
{
if (s>) m2 |= ((s-)<<);
else m1 |= ((s-)<<);
}
bool ck(int s,ll m1,ll m2)
{
if (s>) return (m2&((s-)<<)) != ;
else return (m1&((s-)<<)) != ;
}
void init()
{
memset(head,-,sizeof(head));
memset(head2,-,sizeof(head2));
cnt = cnt2 = ;
}
void add(int u,int v,int w)
{
ed[cnt].v = v;
ed[cnt].w = w;
ed[cnt].n = head[u];
head[u] = cnt++;
ed2[cnt2].v = u;
ed2[cnt2].w = w;
ed2[cnt2].n = head2[v];
head2[v] = cnt2++;
}
int h[N];
bool vis[N];
void spfa(int s,int n)
{
queue<int>q;
memset(vis,,sizeof(vis));
for (int i = ; i <= n; ++i)
h[i] = inf;
q.push(s);
h[s] = ;
vis[s] = true;
while (!q.empty())
{
int u = q.front();
q.pop();
vis[u] = false;
for (int i=head2[u];~i;i=ed2[i].n)
{
int v = ed2[i].v,w = ed2[i].w;
if (h[v]>h[u]+w)
{
h[v] = h[u] + w;
if (!vis[v])
{
vis[v] = true;
q.push(v);
}
}
}
}
}
int ans[N];
void astar(int s,int t,int k)
{
priority_queue<node2> q;
int cnt = , dx = ;
node2 n,n2;
ll m1=,m2=;
sc(s,m1,m2);
st[dx].p = -,st[dx].v = s;
n.set(s,,h[s],dx++,m1,m2);
q.push(n);
while (!q.empty())
{
n = q.top();
q.pop();
if (n.v == t) cnt++;
if (cnt == k)
{
int a = n.dx, b = ;
while (~a)
{
ans[b++] = st[a].v;
a = st[a].p;
}
printf("%d %d\n",n.g,b);
bool ff = false;
for (int i = b-; i >= ; --i)
{
if (ff) printf(" ");
else ff = true;
printf("%d",ans[i]);
}puts("");
return ;
}
for (int i=head[n.v];~i;i=ed[i].n)
{
int v = ed[i].v, w = ed[i].w;
m1 = n.m1, m2 = n.m2;
if (ck(v,m1,m2)) continue;
sc(v,m1,m2);
st[dx].p = n.dx, st[dx].v = v;
n2.set(v,n.g+w,n.g+w+h[v],dx++,m1,m2);
q.push(n2);
}
}
return ;
}
int main()
{
//read;
int n,m,k;
while (~scanf("%d%d%d",&n,&m,&k))
{
init();
int u,v,w,s,t;
for (int i = ; i < m; ++i)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
scanf("%d%d",&s,&t);
spfa(t,n);
astar(s,t,k);
}
return ;
}
SGU 145的更多相关文章
- SGU 145.Strange People(无环K短路)
时间:0.25s空间:4m 题意: 其实就是求无环第K短路. 输入: 给出n,m,k,分别代表,n个点,m条边,第k长路. 接下来m行,三个整数x,y,z,分别代表x,y之间有条费用为x的双向路.保证 ...
- SGU 分类
http://acm.sgu.ru/problemset.php?contest=0&volume=1 101 Domino 欧拉路 102 Coprime 枚举/数学方法 103 Traff ...
- SGU 495. Kids and Prizes
水概率....SGU里难得的水题.... 495. Kids and Prizes Time limit per test: 0.5 second(s)Memory limit: 262144 kil ...
- ACM: SGU 101 Domino- 欧拉回路-并查集
sgu 101 - Domino Time Limit:250MS Memory Limit:4096KB 64bit IO Format:%I64d & %I64u Desc ...
- 【SGU】495. Kids and Prizes
http://acm.sgu.ru/problem.php?contest=0&problem=495 题意:N个箱子M个人,初始N个箱子都有一个礼物,M个人依次等概率取一个箱子,如果有礼物则 ...
- SGU 455 Sequence analysis(Cycle detection,floyd判圈算法)
题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=455 Due to the slow 'mod' and 'div' operati ...
- SGU 422 Fast Typing(概率DP)
题目大意 某人在打字机上打一个字符串,给出了他打每个字符出错的概率 q[i]. 打一个字符需要单位1的时间,删除一个字符也需要单位1的时间.在任意时刻,他可以花 t 的时间检查整个打出来的字符串,并且 ...
- sgu 104 Little shop of flowers 解题报告及测试数据
104. Little shop of flowers time limit per test: 0.25 sec. memory limit per test: 4096 KB 问题: 你想要将你的 ...
- 树形DP求树的重心 --SGU 134
令一个点的属性值为:去除这个点以及与这个点相连的所有边后得到的连通分量的节点数的最大值. 则树的重心定义为:一个点,这个点的属性值在所有点中是最小的. SGU 134 即要找出所有的重心,并且找出重心 ...
随机推荐
- 去面试Python工程师,这几个基础问题一定要能回答,Python面试题No4
今天的面试题以基础为主,去面试Python工程师,这几个基础问题不能答错 第1题:列表和元组有什么不同? 列表和元组是Python中最常用的两种数据结构,字典是第三种. 相同点: 都是序列 都可以存储 ...
- A - 栈
Description You are given a string consisting of parentheses () and []. A string of this type is s ...
- 听dalao讲课 7.26
XFZ今天讲了些关于多项式求ln和多项式求导以及多项式求积分的东西 作为一个连导数和积分根本就不会的蒟蒻,就像在听天书,所以不得不补点前置知识 1.积分 积分是微积分学与数学分析里的一个核心概念.通常 ...
- React Native学习(五)—— 使用插件react-native-scrollable-tab-view
本文基于React Native 0.52 Demo上传到Git了,有需要可以看看,写了新内容会上传的.Git地址 https://github.com/gingerJY/React-Native-D ...
- T1003 电话连线 codevs
http://codevs.cn/problem/1003/ 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 一个国家有n个城市 ...
- Java并发包——线程池
Java并发包——线程池 摘要:本文主要学习了Java并发包中的线程池. 部分内容来自以下博客: https://www.cnblogs.com/dolphin0520/p/3932921.html ...
- element-ui自定义table表头
场景描述: 这个需求的场景很简单,表头自定义居中显示 <el-table-column show-overflow-tooltip prop="telephone" labe ...
- TensorFlow-GPU环境配置之四——配置和编译TensorFlow
首先,使用configure进行配置 配置完成后,使用bazel编译retrain命令,编译命令中加入--config=cuda即为启用GPU 编译进行中... 编译完成 编译完成后,调用retrai ...
- 在虚拟机搭建JStrom
原文:http://blog.csdn.net/u014134180/article/details/51810311 一 安装步骤 二 搭建Zookeeper集群 1 ZooKeeper 单机安装与 ...
- Android: Mac无法找到Android SDK问题
通过brew cask install android-sdk后,Intellij Idea中设置Android SDK路径失败,解决方法如下: /usr/local/Caskroom/android ...