您的位置:首页 > 其它

CF 449B - Jzzhu and Cities(最短路)

2014-07-27 09:12 330 查看
题意:给定n个点,m条边的无向图,现在有一些特殊的路线,可以直接从原点1到达某一个点,现在要去掉一些这样的路线,使得去掉这些路线后,从1到各点的最短路距离不变。求去掉的路线的最大值。

思路:开始写了spfa,T掉了,真是不友好……没办法,写dijkstra吧,最开始要处理一下,如果到某一个点的特殊路线有多个,那么选最短的那条,其他直接去掉就好。。。在djikstra的时候,标记一下插入堆中的路线的类型,表示是否由特殊路线直接走到,不是从特殊路线走的优先级较高,对于从堆中取出结点,如果是由特殊路线走到,那么这条路线就是最短的了,所以这条路不能删掉。记一下数就好了。。。。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<cmath>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn=100000+10;
const int maxm=300000+10;
struct Edge
{
    int v,w,next;
    Edge(int v=0,int w=0,int next=0):v(v),w(w),next(next){}
}edges[maxm<<1];
int head[maxn],nEdge;
int direct[maxn];
ll d[maxn];
bool inq[maxn],flag[maxn];
void AddEdges(int u,int v,int w)
{
    edges[++nEdge]=Edge(v,w,head[u]);
    head[u]=nEdge;
    edges[++nEdge]=Edge(u,w,head[v]);
    head[v]=nEdge;
}
struct HeapNode
{
    ll d;
    int u,type;
    HeapNode(ll d=0,int u=0,int type=0):d(d),u(u),type(type){}
    bool operator < (const HeapNode & a) const
    {
        if(a.d==d) return type<a.type;
        return a.d<d;
    }
};
bool vis[maxn];
int dijkstra(int n)
{
    int cnt=0;
    priority_queue<HeapNode>q;
    memset(vis,0,sizeof(vis));
    memset(flag,0,sizeof(flag));
    for(int i=1;i<=n;++i) d[i]=Inf;
    d[1]=0;
    HeapNode hp=HeapNode(0,1,0);
    for(int i=1;i<=n;++i)
        if(direct[i]!=-1) {cnt++;q.push(HeapNode(direct[i],i,-1));d[i]=direct[i];}
    q.push(hp);
    while(!q.empty())
    {
       hp=q.top();q.pop();
       int u=hp.u;
       if(vis[u]) continue;
       vis[u]=true;
       if(hp.type<0) cnt--;
       for(int k=head[u];k!=-1;k=edges[k].next)
       {
           int v=edges[k].v;
           if(d[v]>=d[u]+edges[k].w)
           {
               d[v]=d[u]+edges[k].w;
               q.push(HeapNode(d[v],v,0));
           }
       }
    }
    return cnt;
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    memset(head,0xff,sizeof(head));
    memset(direct,0xff,sizeof(direct));
    nEdge=-1;
    int u,v,w;
    for(int i=0;i<m;++i)
    {
        scanf("%d%d%d",&u,&v,&w);
        AddEdges(u,v,w);
    }
    int ans=0;
    for(int i=0;i<k;++i)
    {
        scanf("%d%d",&u,&w);
        if(direct[u]==-1) direct[u]=w;
        else direct[u]=min(direct[u],w),ans++;
    }
    ans+=dijkstra(n);
    printf("%d\n",ans);
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: