Codeforces Round #257 (Div. 1) (Codeforces 449B)

题意:给力一张无向图,有一些边是正常道路,有一些边是铁路,问最多能删除几条铁路使得所有点到首都(编号为1)的最短路长度不变。

思路:求不能删除的铁路数,总数减掉就是答案。先求出首都到所有点的最短路,求完最短路后,枚举除首都外所有点,如果这个点被更新的边中只有铁路,那么就有一条铁路不能删除。

注意:这里求最短路一开始用SPFA在第45个点TLE,最后换成带堆优化Dijkstra

#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include <iostream>
#include<queue>
#define M 1000010
#define N 100050
#define LL __int64
#define INF (1000000000000000LL)
using namespace std;
struct node {
    int to, nx, va, flag;
} e[M];
int head[N], ecnt;
struct info {
    int id, va;
};
bool operator<(info a, info b) {
    return a.va > b.va;
}
priority_queue<info> q;
void addedge(int x, int y, int va, int flag) {
    e[ecnt].to = y;
    e[ecnt].va = va;
    e[ecnt].nx = head[x];
    e[ecnt].flag = flag;
    head[x] = ecnt++;
}
bool bo[N];
LL d[N];
int n, m, k;
void Dij() {
    for (int i = 0; i <= n; ++i)
        d[i] = INF;
    memset(bo, 0, sizeof(bo));
    d[1] = 0;
    int st = 0, ed = 0;
    while (!q.empty())
        q.pop();
    info a;
    a.va = 0;
    a.id = 1;
    q.push(a);
    while (!q.empty()) {
        a = q.top();
        q.pop();
        int now = a.id;
        if (bo[now])
            continue;
        bo[now] = true;
        for (int j = head[now]; j != -1; j = e[j].nx) {
            int u = e[j].to;
            if (d[u] > d[now] + e[j].va) {
                d[u] = d[now] + e[j].va;
                a.id=u;
                a.va=d[u];
                q.push(a);
            }
        }
    }
}
void init() {
    scanf("%d%d%d", &n, &m, &k);
    memset(head, -1, sizeof(head));
    ecnt = 0;
    for (int i = 0; i < m; ++i) {
        int x, y, z;
        scanf("%d%d%d", &x, &y, &z);
        addedge(x, y, z, 0);
        addedge(y, x, z, 0);
    }
    for (int i = 0; i < k; ++i) {
        int x, y;
        scanf("%d%d", &x, &y);
        addedge(1, x, y, 1);
        addedge(x, 1, y, 1);
    }
}
void solve() {
    Dij();
    int ans = k;
    for (int i = 2; i <= n; ++i) {
        int flag = 0, flag1 = 0;
        for (int j = head[i]; j != -1; j = e[j].nx) {
            int u = e[j].to;
            if (d[u] + e[j].va == d[i]) {
                if (e[j].flag == 1)
                    flag = 1;
                else
                    flag1 = 1;
            }
        }
        if (flag == 1 && flag1 == 0)
            ans--;
    }
    printf("%d\n", ans);
}
int main() {
    init();
    solve();

}

Codeforces Round #257 (Div. 1) (Codeforces 449B)

时间: 2024-10-15 22:11:30

Codeforces Round #257 (Div. 1) (Codeforces 449B)的相关文章

Codeforces Round #257 (Div. 1) (Codeforces 449D)

思路:定义f(x)为 Ai & x==x  的个数,g(x)为x表示为二进制时1的个数,最后答案为    .为什么会等于这个呢:运用容斥的思想,如果 我们假设 ai&x==x 有f(x)个,那么 这f(x)个 组成集合的子集 & 出来是 >=x那么我们要扣掉>x的 ...  因为这里我们要求的是 & 之后等于0 一开始1个数为0那么就是 1个数为偶数时加上去,  为奇数时减掉了. 那么就剩下求f(x)    .我们把A[i]和x的二进制 分成  前 (20-k)

Codeforces Round #257 (Div. 2)

A.Jzzhu and Children 计算每个人会出现的轮次数,取最后一个且轮次数最大的,注意是用a[i]-1 % m,倒着扫一遍就行了 #include <iostream> #include <cstdio> #include <cstdlib> using namespace std; const int maxn = 100+10; int n, m; int a[maxn]; int main() { #ifdef LOCAL freopen("

Codeforces Round #257 (Div. 2) E题:Jzzhu and Apples 模拟

E. Jzzhu and Apples time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Jzzhu has picked n apples from his big apple tree. All the apples are numbered from 1 to n. Now he wants to sell them to

Codeforces Round #257 (Div. 2) A/B/C/D

前三题早就写好了,一直在纠结D A. Jzzhu and Children 题意:就是简单的模拟,给排成一队的孩子分发糖果,每个孩子有至少要得到的糖果数. 然后每次给队头的孩子分发m个糖果,如果他已经得到了足够的糖果(大于等于他想得到的 最少糖果数)那么他就出队,否则他就去队尾.问最后一个孩子的编号. 算法:队列模拟,水题~ #include<cstdio> #include<iostream> #include<cstring> #include<queue&g

Codeforces Round #257 div.2 D or 450D Jzzhu and Cities【最短路】

Codeforces Round #257 div.2 D or 450D Jzzhu and Cities[最短路] 题目链接:点击打开 题目大意: 在一个国家中有n个城市(城市编号1~n),m条公路和k条铁路,编号为1的城市为首都,为了节约,不需要的铁路需要关闭,问在保证首都到其余所有城市的最短路不变的条件下,最多有多少条铁路是不需要的. 解法: 这个题比较麻烦,保证首都到其余城市的最短路不变,要求出最多有多少条铁路是不需要的,那肯定是从最短路的代码上下手了,我们首先考虑dijkstra算法

Codeforces Round #257(Div.2) D Jzzhu and Cities --SPFA

题意:n个城市,中间有m条道路(双向),再给出k条铁路,铁路直接从点1到点v,现在要拆掉一些铁路,在保证不影响每个点的最短距离(距离1)不变的情况下,问最多能删除多少条铁路 分析:先求一次最短路,铁路的权值大于该点最短距离的显然可以删去,否则将该条边加入图中,再求最短路,记录每个点的前一个点,然后又枚举铁路,已经删去的就不用处理了,如果铁路权值大于该点最短距离又可以删去,权值相等时,该点的前一个点如果不为1,则这个点可以由其他路到达,这条铁路又可以删去. 由于本题中边比较多,最多可以有8x10^

Codeforces Round #257 (Div. 2/A)/Codeforces450A_Jzzhu and Children

解题报告 没什么好说的,大于m的往后面放,,,re了一次,,, #include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; struct node { int x,cd; }num[1000000]; int main() { int n,m,c; cin>>n>>m; int i; for(i=0;i&l

Codeforces Round #257 (Div. 2/B)/Codeforces450B_Jzzhu and Sequences

B解题报告 算是规律题吧,,,x y z -x -y -z 注意的是如果数是小于0,要先对负数求模再加模再求模,不能直接加mod,可能还是负数 给我的戳代码跪了,,, #include <iostream> #include <cstring> #include <cstdio> using namespace std; long long x,y,z; long long n; int main() { cin>>x>>y; cin>&g

Codeforces Round #524 (Div. 2) codeforces 1080A~1080F

目录 codeforces1080A codeforces 1080B codeforces 1080C codeforces 1080D codeforces 1080E codeforces 1080F codeforces1080A 传送门:https://codeforces.com/contest/1080/problem/A 题意:制造一份邀请函需要2份a物品,5份b物品,8份c物品,一个盒子里面有k份物品(可以为a或b或c)问你制造n份邀请函需要用多少个盒子 题解:直接加起来就行