BZOJ 1073: [SCOI2007]kshort

二次联通门 : BZOJ 1073: [SCOI2007]kshort

/*
    BZOJ 1073: [SCOI2007]kshort

       A* k短路
      但是会爆一个点, 是卡A*的
*/
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <cstdlib>

const int BUF = 12313123;
char Buf[BUF], *buf = Buf;
#define Max 120
#define Vec std :: vector
int dis[Max], N, M, S, T, K;
struct D
{
    Vec <int> r; bool is[Max]; int u, d;
    bool operator < (const D A) const
    {
        return this->d + dis[this->u] > A.d + dis[A.u];
    }
};
bool visit[Max];
struct E { E *n; int v, d; };
E *Z_list[Max], *F_list[Max], poor[(Max * Max) << 1], *Ta = poor;
inline int read (int &now)
{
    for (now = 0; !isdigit (*buf); ++ buf);
    for (; isdigit (*buf); now = now * 10 + *buf - ‘0‘, ++ buf);
}
void Spfa ()
{
    std :: queue <int> Q; memset (dis, 0x3f, sizeof dis); int n; E *e;
    for (Q.push (T), dis[T] = 0, visit[T] = true; !Q.empty (); Q.pop ())
    {
        n = Q.front (); visit[n] = false;
        for (e = F_list[n]; e; e = e->n)
            if (dis[e->v] > dis[n] + e->d)
            {
                dis[e->v] = dis[n] + e->d;
                if (!visit[e->v]) visit[e->v] = true, Q.push (e->v);
            }
    }
}
Vec <D> Answer; int C;
inline int min (int a, int b) { return a < b ? a : b; }
bool Comp (D A, D B)
{
    if (A.d != B.d) return A.d < B.d;
    int L = min (A.r.size (), B.r.size ());
    for (register int i = 0; i < L; ++ i)
        if (A.r[i] != B.r[i]) return A.r[i] < B.r[i];
    return A.r.size () < B.r.size ();
}
void A_star ()
{
    std :: priority_queue <D> H; D n, res; n.u = S, n.d = 0;
    n.r.push_back (S); E *e; n.is[S] = true; H.push (n);
    for (; !H.empty (); )
    {
        n = H.top (); H.pop ();
        if (n.u == T)
        {
            if ((++ C) > K && n.d > Answer[K - 1].d) break;
            Answer.push_back (n);
        }
        for (e = Z_list[n.u]; e; e = e->n)
            if (!n.is[e->v])
            {
                res = n; res.u = e->v; res.r.push_back (e->v);
                res.d = e->d + n.d, res.is[e->v] = true, H.push (res);
            }
    }
    if (Answer.size () < K) { printf ("No\n"); exit (0); }
    std :: sort (Answer.begin (), Answer.end (), Comp);
}

int Main ()
{
    fread (buf, 1, BUF, stdin); read (N), read (M), read (K);
    read (S), read (T); register int i; int x, y, z, Size;
    for (i = 1; i <= M; ++ i)
    {
        read (x), read (y), read (z);
        ++ Ta, Ta->v = y, Ta->d = z, Ta->n = Z_list[x], Z_list[x] = Ta;
        ++ Ta, Ta->v = x, Ta->d = z, Ta->n = F_list[y], F_list[y] = Ta;
    }
    for (Spfa (), A_star (), i = 0, Size = Answer[K - 1].r.size () - 1; i < Size; ++ i)
        printf ("%d-", Answer[K - 1].r[i]);
    printf ("%d", Answer[K - 1].r[i]);
    return 0;
}
int ZlycerQan = Main (); int main (int argc, char *argv[]) {;}
时间: 2024-10-14 00:39:48

BZOJ 1073: [SCOI2007]kshort的相关文章

bzoj1073[SCOI2007]kshort

1073: [SCOI2007]kshort Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1483  Solved: 373[Submit][Status][Discuss] Description 有n个城市和m条单向道路,城市编号为1~n.每条道路连接两个不同的城市,且任意两条道路要么起点不同要么终点不同,因此n和m满足m<=n(n-1).给定两个城市a和b,可以给a到b的所有简单路(所有城市最多经过一次,包括起点和终点)排序:先按长度从小

cogs 2342. [SCOI2007]kshort

2342. [SCOI2007]kshort k短路 #include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<cstdio> #include<cmath> #include<queue> using namespace std; #define maxn 23333 #define inf 0x3f3f3f3f

[BZOJ 1066] [SCOI2007] 蜥蜴 【最大流】

题目链接:BZOJ - 1066 题目分析 题目限制了高度为 x 的石柱最多可以有 x 只蜥蜴从上面跳起,那么就可以用网络流中的边的容量来限制.我们把每个石柱看作一个点,每个点拆成 i1, i2,从 i1 到 i2 连一条边,容量为这个石柱 i 的高度,即跳跃次数限制.来到这个石柱就是向 i1 连边,从这个石柱跳起就是从 i2 向外连边,这样只要从石柱 i 跳起就一定会消耗 i1 到 i2 的边的容量.如果 i 有蜥蜴,就从 S 到 i1 连一条容量为 1 的边,如果从石柱 i 能跳出边界,就从

BZOJ 1072 [SCOI2007]排列perm

考虑到s的长度特别小,只有10,可以考虑状压dp. 设F[S][d]表示当选了集合S(用二进制压位表示)中的所有位置,对D取模的结果为d的方案总数:不难想到转移和初始化. 初始化:F[0][0]=1  0在这里表示空集合 转移:F[S][(d * 10 + s[i]-'0') % D]=sum{F[S0][d]}  S0是S的一个子集,并且刚好只比S少一个元素i 注意,重复的数字被算了多遍.样例当中就有.因此最后的答案要除以所有重复的数字个数的阶乘. 看代码就明白啦~ (再补充一个要用到状压技巧

BZOJ 1070: [SCOI2007]修车(最小费用最大流)

建图很神奇..建完图其实就是裸的费用流了.. -------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<vector> #include<queue> #define rep(i,n) for(int i

bzoj 1070: [SCOI2007]修车 -- 费用流

1070: [SCOI2007]修车 Time Limit: 1 Sec  Memory Limit: 128 MB Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. Input 第一行有两个m,n,表示技术人员数与顾客数. 接下来n行,每行m个整数.第

bzoj 1068: [SCOI2007]压缩 DP

1068: [SCOI2007]压缩 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 496  Solved: 315[Submit][Status] Description 给一个由小写字母组成的字符串,我们可以用一种简单的方法来压缩其中的重复信息.压缩后的字符串除了小写字母外还可以(但不必)包含大写字母R与M,其中M标记重复串的开始,R重复从上一个M(如果当前位置左边没有M,则从串的开始算起)开始的解压结果(称为缓冲串). bcdcdcdcd可以

bzoj 1067: [SCOI2007]降雨量 模擬

1067: [SCOI2007]降雨量 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2010  Solved: 503[Submit][Status] Description 我们常常会说这样的话:“X年是自Y年以来降雨量最多的”.它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年.例如2002,2003,2004和2005年的降雨量分别为4920,5901,2832和3890,则可以说“2005年是自2003年以

bzoj 1069 [SCOI2007]最大土地面积(旋转卡壳)

1069: [SCOI2007]最大土地面积 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2277  Solved: 853[Submit][Status][Discuss] Description 在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成的多边形面积最大. Input 第1行一个正整数N,接下来N行,每行2个数x,y,表示该点的横坐标和纵坐标. Output 最大的多边形面积,答案精确到小