zoukankan      html  css  js  c++  java
  • codeforces144——D. Missile Silos(最短路+枚举)

    codeforces144——D. Missile Silos

    原题链接

    题意:

    给定一个n点m边的无向图,给定起点,求和起点最短距离为l的点有多少个(可以是点也可以在边上)

    思路:

    首先求一遍最短路,处理出每个点到起点的最短距离,这样遍历一遍点就可以求出和起点最短距离为l的点的个数。

    再来考虑该点在边上的情况,我们遍历每条边,如果该点在边上,假设边的顶点为u和v,无非三种情况,一是该点在u和v的中点上,二是该点更加靠近u,三是该点更加靠近v。

    接下来将逐一分析。我们假设起点S,边的顶点u,v的关系如下图。

    在这里插入图片描述
    当该点在u,v中点时,一定满足dis[u]+dis[v]+w==2*l;
    当该点更靠近u时,首先就是dis[u]<l,说明该点不在s和u的中间;再就是l-dis[u]<w,说明多出来的这部分不会超过v;然后就是w-(l-dis[u])>l-dis[v],说明该点到u的距离小于该点到v的距离,即该点更靠近u。
    当该点更靠近v时也同理。
    具体细节如下:

    int u=edge[j].u,v=edge[j].e,w=edge[j].w;
    if(dis[u]<l&&l-dis[u]<w&&w-l+dis[u]>l-dis[v]) res++;//更靠近u
    if(dis[v]<l&&l-dis[v]<w&&w-l+dis[v]>l-dis[u]) res++;//更靠近v
    if(dis[u]<l&&dis[v]<l&&dis[u]+dis[v]+w==l*2) res++;///在重点
    

    代码:

    ///#pragma GCC optimize(3)
    ///#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
    ///#pragma GCC optimize(2)
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<ll,ll>PLL;
    typedef pair<int,int>PII;
    typedef pair<double,double>PDD;
    #define I_int ll
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    char F[200];
    inline void out(I_int x) {
        if (x == 0) return (void) (putchar('0'));
        I_int tmp = x > 0 ? x : -x;
        if (x < 0) putchar('-');
        int cnt = 0;
        while (tmp > 0) {
            F[cnt++] = tmp % 10 + '0';
            tmp /= 10;
        }
        while (cnt > 0) putchar(F[--cnt]);
        //cout<<" ";
    }
    ll ksm(ll a,ll b,ll p){ll res=1;while(b){if(b&1)res=res*a%p;a=a*a%p;b>>=1;}return res;}
    const int inf=0x3f3f3f3f,mod=998244353;
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const int maxn=1e6+7,maxm=3e5+7,N=1e6+7;
    const double PI = atan(1.0)*4;
    
    int n,m,s;
    struct node{
        int e,ne,w,u;
    }edge[maxn];
    int h[maxn],idx;
    
    void add(int u,int v,int w){
        edge[idx].u=u,edge[idx].e=v,edge[idx].w=w,edge[idx].ne=h[u],h[u]=idx++;
    }
    
    int dis[maxn],st[maxn];
    
    void spfa(int s){
    	memset(dis,0x3f,sizeof dis);
        queue<int>q;
        q.push(s);dis[s]=0;st[s]=1;
        while(!q.empty()){
            int t=q.front();q.pop();
            st[t]=0;
            for(int i=h[t];i!=-1;i=edge[i].ne){
                int j=edge[i].e;
    			if(dis[j]>dis[t]+edge[i].w){
    				dis[j]=dis[t]+edge[i].w;
    				if(!st[j]){
    					q.push(j);
    					st[j]=1;
    				}
    			}
            }
        }
    }
    
    
    int main(){
        memset(h,-1,sizeof h);
        n=read(),m=read(),s=read();
        for(int i=1;i<=m;i++){
            int u=read(),v=read(),w=read();
            add(u,v,w);add(v,u,w);
        }
        int l=read();
        spfa(s);
        int res=0;
        for(int i=1;i<=n;i++)
        	if(dis[i]==l) res++;
    	
    	for(int j=0;j<idx;j+=2){
    		int u=edge[j].u,v=edge[j].e,w=edge[j].w;
        	if(dis[u]<l&&l-dis[u]<w&&w-l+dis[u]>l-dis[v]) res++;
        	if(dis[v]<l&&l-dis[v]<w&&w-l+dis[v]>l-dis[u]) res++;
        	if(dis[u]<l&&dis[v]<l&&dis[u]+dis[v]+w==l*2) res++;
    	}
        out(res);
        return 0;
    }
    
  • 相关阅读:
    HBase with MapReduce (MultiTable Read)
    HBase with MapReduce (SummaryToFile)
    HBase with MapReduce (Summary)
    HBase with MapReduce (Read and Write)
    HBase with MapReduce (Only Read)
    Hbase中的BloomFilter(布隆过滤器)
    HBase的快照技术
    How To Use Hbase Bulk Loading
    Cloudera-Manager修改集群的IP
    Java中的HashSet和TreeSet
  • 原文地址:https://www.cnblogs.com/OvOq/p/14853113.html
Copyright © 2011-2022 走看看