zoukankan      html  css  js  c++  java
  • Travel Guide

    链接: 2018-2019 ICPC Southwestern European Regional Programming Contest (SWERC 2018)

    题意:

    一个无向图,图上有三个关键点A,B,C,统计图上点u的个数,满足没有其他点v到A,B,C的最短距离都比u到A,B,C的最短距离小(uA>=vA && uB>=vB && uC>=vC &&(uA>vA || uB>vB || uC>vC) )

    解法:

    先跑3次dijkstra,求出所有点到A,B,C的距离,然后按照到A的距离从小到大排序。从前往后遍历,用线段树查询此时<=b的最小C值,如果比当前C大,该点就加入答案中。

    考虑到距离相等的情况,先用map去重,并记录重复点的个数,每次加入答案的就是点的个数。

    因为距离最大有5e7,需要把距离离散化

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int INF = 1e9;
    const int maxn = 1e5 + 5;
    const int maxm = 2e5 + 5;
    struct node {
    	int id, cost;
    	node(int a = 0, int b = 0) :id(a), cost(b) {}
    	bool operator<(const node &b)const {
    		return cost > b.cost;//将小的放上面
    	}
    };
    struct edge {
    	int v, cost;
    	edge(int a = 0, int b = 0) :v(a), cost(b) {}
    };
    vector<edge>E[maxm];
    int dis[3][maxn];
    bool vis[maxn];
    void dijkstra(int n, int start,int *lowcost) {
    	fill(vis + 1, vis + 1 + n, 0);
    	fill(lowcost + 1, lowcost + 1 + n, INF);
    	priority_queue<node>q;
    	lowcost[start] = 0;
    	q.push(node(start, 0));
    	while (!q.empty()) {
    		int u = q.top().id;
    		q.pop();
    		if (vis[u])continue;
    		vis[u] = 1;
    		for (int i = 0; i < E[u].size(); i++) {
    			int v = E[u][i].v;
    			int cost = E[u][i].cost;
    			if (!vis[v] && lowcost[v] > lowcost[u] + cost) {
    				lowcost[v] = lowcost[u] + cost;
    				q.push(node(v, lowcost[v]));
    			}
    		}
    	}
    }
    void addedge(int u, int v, int w) {
    	E[u].push_back(edge(v, w));
    }
    struct Point{
        int a,b,c;
        operator<(const Point &B)const{
            if(a!=B.a){
                return a<B.a;
            }
            else if(b!=B.b){
                return b<B.b;
            }
            else{
                return c<B.c;
            }
        }
    }p[maxn];
    int lisan[maxn*3];
    int lisancnt=0;
    
    //------线段树-------------
    const int M=1<<19;//从1开始,不能修改0和M
    int T[M+M];
    void modify(int n,int v){
    	for(T[n+=M]=v,n>>=1;n;n>>=1)
    		T[n]=min(T[n+n],T[n+n+1]);
    }
    int query(int l,int r){
    	int rmin=INF,lmin=INF;
    	for(l+=M-1,r+=M+1;l^r^1;l>>=1,r>>=1){
    		if(~l&1) lmin=min(lmin,T[l^1]);
    		if(r&1) rmin=min(rmin,T[r^1]);
    	}
    	return min(lmin,rmin);
    }
    //------------------------
    
    int main() {
    	int n, m, u, v, w;
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= m; i++) {
    		scanf("%d%d%d", &u, &v, &w);
    		u++; v++;
    		addedge(u, v, w);
    		addedge(v, u, w);
    	}
    	dijkstra(n, 1, dis[0]);
    	dijkstra(n, 2, dis[1]);
    	dijkstra(n, 3, dis[2]);
    	for (int i = 1; i <= n; i++) {
    		p[i]={dis[0][i],dis[1][i],dis[2][i]};
    	}
    	map<Point,int>MA;
    	for(int i=1;i<=n;i++){
            lisan[++lisancnt]=p[i].a;
            lisan[++lisancnt]=p[i].b;
            lisan[++lisancnt]=p[i].c;
    	}
    	sort(lisan+1,lisan+1+lisancnt);
    	int lisansize=unique(lisan+1,lisan+1+lisancnt)-(lisan + 1);
    	for(int i=1;i<=n;i++){
            p[i].a=lower_bound(lisan+1,lisan+1+lisansize,p[i].a)-lisan;
            p[i].b=lower_bound(lisan+1,lisan+1+lisansize,p[i].b)-lisan;
            p[i].c=lower_bound(lisan+1,lisan+1+lisansize,p[i].c)-lisan;
            MA[p[i]]++;
    	}
    	int cnt=0;
    	for(auto poi:MA){
            p[++cnt]=poi.first;
    	}
    	sort(p+1,p+1+cnt);
        int ans=0;
        fill(T,T+M+M-1,INF);
        for(int i=1;i<=cnt;i++){
            if(query(1,p[i].b)>p[i].c){//该点是有用的
                ans+=MA[p[i]];
                modify(p[i].b,p[i].c);
            }
        }
        printf("%d
    ",ans);
    }
    /*
    5 4
    0 3 1
    1 3 1
    2 3 1
    4 3 1
    
    5 6
    0 3 1
    1 3 1
    2 3 1
    4 3 1
    0 1 1
    0 2 1
    */
    
  • 相关阅读:
    Andriod开发环境配置
    Java调用WebService
    Message Modem Develop
    Call .so in Linux
    How to unpack a tar file in windows
    Visual Studio 2010工程目录下的ipch文件夹和.sdf文件
    TWAIN学习记录
    几种调用扫描仪的方案
    Gzip Practice
    Twain Practice
  • 原文地址:https://www.cnblogs.com/ucprer/p/12901437.html
Copyright © 2011-2022 走看看