Codeforces_449B 最短路+统计

也是给这个题目跪了一天。。。时间不多了,也不多讲

首先要用 nlogn的优先队列dijstla来求最短路,n^2的会超时,不过发现SPFA好像也可以过,他的复杂度应该介于NlogN和N^2之间。

然后统计可以去掉的铁路条数才是难点

一开始我采用边跑最短路边标记,最后再统计,发现漏了好多情况,自己想了个数据都过不了,即如果当前的铁道和另外一个铁路都能访问该点,实际应该去掉当前的这个铁路,但我这种方案根本探测不出来这种情况

最好的方法就是边跑最短路边探测了,聪哥就是这样做,然后我还是谨慎了些,采用数组记录,但是我坑在一个地方,就是优先队列的时候,我调用外部的数组值作为比较函数的变量,然后总是过不了第六组数据,最后发现是这个问题。真是坑死人,优先队列的比较函数一定只能调用内部值,千万别调外部的,血泪教训啊

还有个坑的地方就是我用的邻接表是先访问火车路,再访问公路,不像聪哥是先访问公路,后来铁路一上来,直接比较就行了。。。我这样的,有可能铁路边一出来就变成了最短边,但其实还有可能公路能访问到他,距离相等的公路,那么这个铁边就要去掉了,所以在里面孩子就算被vis了,也特判一下是不是铁路边以及距离相等。

有很多废弃边,尤其是连接一个点可能有多条铁路,在读入数据的时候,就处理掉这些,只留下一个边,这些边留下不仅增加复杂度,还可能造成错误,因为不好判断

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define LL __int64
using namespace std;
int n,m,k;
const int N = 9*100000+80;
int u[N],v[N],nt[N],flag[N],ft[N/8];
__int64 e[N];
__int64 d[N/8];
const LL INF =1LL<<62;
int vis[N/8];
int inq[N/8];
int cnt;
int isq[N/8];
struct node
{
    int x,val;
    bool operator < (const node& rhs) const{
        return val>rhs.val;
    }
};
void add(int a,int b,int c,int f)
{
    u[cnt]=a;
    v[cnt]=b;
    e[cnt]=(LL)c;
    flag[cnt]=f;
    nt[cnt]=ft[a];
    ft[a]=cnt++;
}
priority_queue<node> q;
void dijstla()
{
    while (!q.empty()) q.pop();
    d[1]=0;
    q.push((node){1,0});
    while (!q.empty())
    {
        node tmp=q.top();
        q.pop();
        int ux=tmp.x;
        if (vis[ux]) continue;
        vis[ux]=1;
        isq[ux]=0;
        for (int i=ft[ux];i!=-1;i=nt[i]){
            int vx=v[i];
            if (d[vx]>d[ux]+e[i]){
                if (inq[vx]>0 && flag[i]==0 && ((d[ux]+e[i])<=inq[vx])){
                    inq[vx]=0;
                }
                d[vx]=d[ux]+e[i];
                //if (isq[vx]) continue;
               // else {
                q.push((node){vx,d[vx]});
                //isq[vx]=1;
               // }
            }
            else
            if (d[vx]==d[ux]+e[i])
            {
                if (flag[i]==0){
                    inq[vx]=0;
                }
            }
            else
            if (flag[i]==1){
                inq[vx]=0;
            }
        }
    }
}
int main()
{
    int a,b,c;
    while (scanf("%d%d%d",&n,&m,&k)!=EOF)
    {
        int ans=0;
        cnt=0;
        for (int i=0;i<=n;i++){
             ft[i]=-1;
             d[i]=INF;
             vis[i]=0;
             inq[i]=-1;
             isq[i]=0;
        }
        for (int i=0;i<m;i++){
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c,0);
            add(b,a,c,0);
        }
        int tmp=0;
        for (int i=0;i<k;i++){
            scanf("%d%d",&a,&b);
            if (inq[a]==-1){
                inq[a]=b;
            }
            else {
                ans++;
                if (inq[a]>b) inq[a]=b;
            }
        }
        for (int i=2;i<=n;i++){
            if (inq[i]>0){
                add(1,i,inq[i],1);
            }
        }
        dijstla();
        for (int i=ft[1];i!=-1;i=nt[i]){
            int nx=v[i];
            if (flag[i]==1){
                if (inq[nx]==0){
                    ans++;
                }
                else
                if (inq[nx]>0)
                {
                    if (d[nx]<inq[nx]){
                        ans++;
                    }
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

  

Codeforces_449B 最短路+统计

时间: 2024-10-27 07:32:40

Codeforces_449B 最短路+统计的相关文章

poj 3463 最短路与次短路&amp;&amp;统计个数

题意:求最短路和比最短路长度多1的次短路的个数 本来想图(有)方(模)便(版)用spfa的,结果妹纸要我看看dijkstra怎么解.... 写了三遍orz Ver1.0:堆优化+邻接表,WA 1 //不能用堆优化+邻接表,因为需要处理dis[i][0]和dis[i][1]两套,如果都挤到一个堆里就乱套了 2 3 #include <iostream> 4 #include <cstdio> 5 #include <queue> 6 #include <cstrin

Codeforces Round #623 (Div. 2, based on VK Cup 2019-2020 - Elimination Round, Engine)

题目链接:https://codeforces.com/contest/1315 A - Dead Pixel 诚心诚意的送分题. 题意:给一个n*m的格子矩阵,和一个坏掉的格子,找一个最大的不包含坏掉的格子的矩阵. void test_case() { int n, m, x, y; scanf("%d%d%d%d", &n, &m, &x, &y); int ans = max(x * m, (n - (x + 1)) * m); ans = max

poj 3463 Sightseeing(次短路+条数统计)

/* 对dij的再一次理解 每个点依旧永久标记 只不过这里多搞一维 0 1 表示最短路还是次短路 然后更新次数相当于原来的两倍 更新的时候搞一下就好了 */ #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<vector> #define maxn 1010 using namespace std; int T,n,m,num,head[m

Luogu P1608 路径统计 最短路计数

颓了...重边导致我乖乖用邻接矩阵.... 好吧就是个最短路计数....如果更新时d[v]==d[u]+w[i],就可以接起来,把两个加在一起.. 如果d[v]>d[u]+w[i],那么c[v]直接赋值为c[u],相当于这个最短路是由u转移过来的. #include<cstdio> #include<iostream> #include<cstring> #include<queue> #define R register int using name

洛谷——P1608 路径统计

P1608 路径统计 题目描述 “RP餐厅”的员工素质就是不一般,在齐刷刷的算出同一个电话号码之后,就准备让HZH,TZY去送快餐了,他们将自己居住的城市画了一张地图,已知在他们的地图上,有N个地方,而且他们目前处在标注为“1”的小镇上,而送餐的地点在标注为“N”的小镇.(有点废话)除此之外还知道这些道路都是单向的,从小镇I到J需要花费D[I,J]的时间,为了更高效快捷的将快餐送到顾客手中, 他们想走一条从小镇1到小镇N花费最少的一条路,但是他们临出发前,撞到因为在路上堵车而生气的FYY,深受启

习题:破坏基地(最短路+计数)

破坏基地(tyvj2040) 描述 在Z国和W国之间一直战火不断.好不容易,W国的间谍把完整的Z国的军事基地的地图到手了.于是W国决定再次出击,一举击破Z国的防线.W国认真研究了Z国的地形,发现Z国有N个军事基地,我们不妨编号成1..N,而且经过深刻研究,发现1号军事基地是资源补给基地,而N号军事基地是前线.由于地形的缘故,只有M对军事基地两两可达,当然是有距离的.此时W国的弹头紧缺,当下的弹头只能去毁灭一个军事基地.当然了,最重要的就是毁灭一个军事基地,使得资源补给基地与前线的最短距离发生变化

再探第k短路

其实这是一个很古老的姿势啦- 只不过今天跟同学讨论A*算法求k短路的时候,同学不信A*算法能被卡掉. 于是我翻了翻课件找出了一种n元环的特殊情况,卡掉了A*算法. A*算法是只有到达终点的时候才能统计答案,这导致可能拓展很多个状态才能得到一个用来更新答案的有效状态. 例如一个n元环,当我们到达终点之后,可能还要拓展n次才能得到下一个状态.于是若求k短路时间复杂度就为O(nk).于是就容易被卡掉. 我们考虑换一种方式来定义一条从起点s到终点t的路径. 构建出以t为终点的最短路树,t是这棵树的根,对

codeforces 144D Missile Silos(最短路)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Missile Silos A country called Berland consists of n cities, numbered with integer numbers from 1 to n. Some of them are connected by bidirectional roads. Each road has some length. There is

洛谷 P1608 路径统计

题目描述 “RP餐厅”的员工素质就是不一般,在齐刷刷的算出同一个电话号码之后,就准备让HZH,TZY去送快餐了,他们将自己居住的城市画了一张地图,已知在他们的地图上,有N个地方,而且他们目前处在标注为“1”的小镇上,而送餐的地点在标注为“N”的小镇.(有点废话)除此之外还知道这些道路都是单向的,从小镇I到J需要花费D[I,J]的时间,为了更高效快捷的将快餐送到顾客手中, 他们想走一条从小镇1到小镇N花费最少的一条路,但是他们临出发前,撞到因为在路上堵车而生气的FYY,深受启发,不能仅知道一条路线