节点不可重复经过的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. CF1065D Three Pieces

    题目描述:给出一个n*n的棋盘,棋盘上每个格子有一个值.你有一个子,要求将这个子从1移到n*n(去k时可以经过比k大的点). 开局时它可以作为车,马,相(国际象棋).每走一步耗费时间1.你也可以中途将 ...

  2. Linux环境搭建SVN服务

    一.准备工作 首先要保证自己的linux电脑能上外网,我这电脑因为是新的,没有配置网络,所以再这块花费了点时间. 1.检查ip信息 >ifconfig 2.检查DNS服务器 >cat  / ...

  3. Buffer.isBuffer()详解

    Buffer.isBuffer(obj) obj {Object} 返回:{Boolean} 如果 obj 是一个 Buffer 则返回 true.

  4. Android四大核心组件之Activity

    一.活动生命周期 二.生命周期执行介绍 当该页面(Activity)被启动时 会执行onCreate().onStart().onRestart()这三个方法, 只有当onRestart() 方法执行 ...

  5. [学习资料] Tiny210(S5PV210) u-boot移植

    Tiny210(S5PV210) u-boot移植http://www.microoh.com/bbs/forum.php?mod=viewthread&tid=254&fromuid ...

  6. Python 中的变量还能这样理解(白话)

    一.案例分析 1.思考 计算软件测试大佬柠檬小姐姐,每月能存多少钱 # 计算软件测试大佬柠檬小姐姐,每月能存多少钱 # 坐标:深圳 # 2018年1月份 # 房租水电 4000元 # 伙食费 1000 ...

  7. SQL-如何使用 MongoDB和PyMongo。

    先决条件 在开始之前,请确保已经安装了 PyMongo 发行版. 在 Python shell 中,下面的代码应该在不引发异常的情况下运行: >>> import pymongo 假 ...

  8. 商业研究(20):滴滴出行,进军海外包车?与OTA携程和包车创业公司,共演“三国杀”?看看分析师、投资人和权威人士等10个人的观点碰撞

     小雷友情提示:创业有风险,投资需谨慎.      前一篇文章,在探讨境外游创业公司-皇包车和易途8的时候,提到"滴滴如果进军海外包车,为海外华人提供打车和包车服务,有较大可能对海外包车公司 ...

  9. BNUOJ 7697 Information Disturbing

    Information Disturbing Time Limit: 3000ms Memory Limit: 65536KB This problem will be judged on HDU. ...

  10. 关于oracle 压缩表

    这周客户的问题非常多,总是说我的数据不对.于是我对数据梳理了以后发现以前认为是重复数据的,其实并不是,而是我忽略了一个维度.那么这样一来,我们的周详单表就会有500多万的数据.一个月按照4周计算,就要 ...