节点不可重复经过的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的更多相关文章

  1. SGU 145.Strange People(无环K短路)

    时间:0.25s空间:4m 题意: 其实就是求无环第K短路. 输入: 给出n,m,k,分别代表,n个点,m条边,第k长路. 接下来m行,三个整数x,y,z,分别代表x,y之间有条费用为x的双向路.保证 ...

  2. SGU 分类

    http://acm.sgu.ru/problemset.php?contest=0&volume=1 101 Domino 欧拉路 102 Coprime 枚举/数学方法 103 Traff ...

  3. SGU 495. Kids and Prizes

    水概率....SGU里难得的水题.... 495. Kids and Prizes Time limit per test: 0.5 second(s)Memory limit: 262144 kil ...

  4. ACM: SGU 101 Domino- 欧拉回路-并查集

    sgu 101 - Domino Time Limit:250MS     Memory Limit:4096KB     64bit IO Format:%I64d & %I64u Desc ...

  5. 【SGU】495. Kids and Prizes

    http://acm.sgu.ru/problem.php?contest=0&problem=495 题意:N个箱子M个人,初始N个箱子都有一个礼物,M个人依次等概率取一个箱子,如果有礼物则 ...

  6. 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 ...

  7. SGU 422 Fast Typing(概率DP)

    题目大意 某人在打字机上打一个字符串,给出了他打每个字符出错的概率 q[i]. 打一个字符需要单位1的时间,删除一个字符也需要单位1的时间.在任意时刻,他可以花 t 的时间检查整个打出来的字符串,并且 ...

  8. sgu 104 Little shop of flowers 解题报告及测试数据

    104. Little shop of flowers time limit per test: 0.25 sec. memory limit per test: 4096 KB 问题: 你想要将你的 ...

  9. 树形DP求树的重心 --SGU 134

    令一个点的属性值为:去除这个点以及与这个点相连的所有边后得到的连通分量的节点数的最大值. 则树的重心定义为:一个点,这个点的属性值在所有点中是最小的. SGU 134 即要找出所有的重心,并且找出重心 ...

随机推荐

  1. 笔试算法题(47):简介 - B树 & B+树 & B*树

    B树(B-Tree) 1970年由R. Bayer和E. Mccreight提出的一种适用于外查找的树,一种由BST推广到多叉查找的平衡查找树,由于磁盘的操作速度远小于存储器的读写速度,所以要求在尽量 ...

  2. YUM:Yellow dog Updater Modified

    1. 什么是YUM YUM(全称为 Yellow dog Updater Modified) 是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器.基于RPM包管理,能够从 ...

  3. C#基础学习(二)

    ---恢复内容开始--- 面向对象 (类是不占内存,实例占内存) C#与python不用可以直接从另一个文件直接实例化一个类,不需要导包:                                ...

  4. 杭电 1789 Doing Homework again (贪心 求最少扣分)

    Description zichen has just come back school from the 30th ACM/ ICPC. Now he has a lot of homework t ...

  5. typeof instanceof操作符的相关知识

    数据类型 ECMAScript中有5中基本数据类型:Undefined Null Boolean Number String. Typeof运算符 对一个值使用typeof操作符可能返回下列某个字符串 ...

  6. python之字符串处理 2014-4-5

    #字符串 p62 13:20pm-15:20 上一章讲的所有的序列化操作对于字符串同样适用 不过字符串不可变 所以无法使用分片赋值 1.字符串格式化 >>> format=" ...

  7. python接口测试之Http请求(三)

    python的强大之处在于提供了很多的标准库,这些标准库可以直接调用,本节部分,重点学习和总结在 接口测试中Python的Http请求的库的学习. 首先来看httplib,官方的解释为:本模块定义了类 ...

  8. Rsync文件同步服务器配置

    rsync 是一个Unix/Linux系统下的文件同步和传输工具.rsync是用 “rsync 算法”提供了一个客户机和远程文件服务器的文件同步的快速方法.可以用来做备份或镜像.一.配置文件rsync ...

  9. ORACLE数据库查看执行计划的方法

    一.什么是执行计划(explain plan) 执行计划:一条查询语句在ORACLE中的执行过程或访问路径的描述. 二.如何查看执行计划 1: 在PL/SQL下按F5查看执行计划.第三方工具toad等 ...

  10. HDU 3537 Mock Turtles型翻硬币游戏

    题目大意: 每次可以翻1个或者2个或者3个硬币,但要保证最右边的那个硬币是正面的,直到不能操作为输,这题目还有说因为主人公感情混乱可能描述不清会有重复的硬币说出,所以要去重 这是一个Mock Turt ...