HDU 1491 社交网络(最短路计数)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1491

题意:给出一个联通的无向图,边有权值。定义I(v)如下,计算每个点的I值。

HDU 1491 社交网络(最短路计数)_第1张图片

思路:(1)最简单的就是那个floyd了。。。g[i][j]记录最短路长度,f[i][j]记录个数,不多说了;

(2)下面说说我自己想出来的算法。。枚举s和t,计算每个点到s和t的最短路。。然后建立最短路树。。之后求s到t的最短路个数。。然后枚举删掉某个点再求最短路个数,则差值即为通过删掉点的最短路数目。。。求最短路数目用优先队列。。

 

struct node
{
    int u,v,w,next;
};
 
node edges[N*N];
int head[N],e;
 
void Add(int u,int v,int w)
{
    edges[e].u=u;
    edges[e].v=v;
    edges[e].w=w;
    edges[e].next=head[u];
    head[u]=e++;
}
 
node edges1[N*N];
int head1[N],e1;
 
void Add1(int u,int v,int w)
{
    edges1[e1].u=u;
    edges1[e1].v=v;
    edges1[e1].w=w;
    edges1[e1].next=head1[u];
    head1[u]=e1++;
}
 
int n,m;
double ans[N];
 
int dis1[N],dis2[N];
int visit[N],T;
 
void BFS(int s,int dis[])
{
    T++;
    int i;
    FOR1(i,n) dis[i]=INF;
    dis[s]=0;
    queue<int> Q;
    Q.push(s);
    int u,v,w;
    while(!Q.empty())
    {
        u=Q.front();
        Q.pop();
         
        visit[u]--;
        for(i=head[u];i!=-1;i=edges[i].next)
        {
            v=edges[i].v;
            w=edges[i].w;
            if(dis[v]>dis[u]+w)
            {
                dis[v]=dis[u]+w;
                if(visit[v]!=T)
                {
                    visit[v]=T;
                    Q.push(v);
                }
            }
        }
    }
}
 
struct Node
{
    int u,dis;
     
    Node(){}
    Node(int _u,int _dis)
    {
        u=_u;
        dis=_dis;
    }
     
    int operator<(const Node &a) const
    {
        return dis>a.dis;
    }
};
 
i64 cnt[N];
 
i64 cal(int s,int t,int x)
{
    priority_queue<Node> Q;
    Q.push(Node(s,0));
    clr(cnt,0); cnt[s]=1;
    Node p;
    int u,v,w,i,L=dis1[t];
    int h[N]={0}; 
    while(!Q.empty())
    {
        p=Q.top();
        Q.pop();
         
        u=p.u; h[u]=0;
        for(i=head1[u];i!=-1;i=edges1[i].next)
        {
            v=edges1[i].v;
            w=edges1[i].w;
            if(v==x) continue;
            if(p.dis+w+dis2[v]==L)
            {
                cnt[v]+=cnt[u];
                if(!h[v]) h[v]=1,Q.push(Node(v,p.dis+w));
            }
        }
    }
    return cnt[t];
}
 
void deal(int s,int t)
{
    BFS(s,dis1); BFS(t,dis2);
    clr(head1,-1); e1=0;
    int L=dis1[t],i,u,v,w;
    int h[N]={0};
    FOR0(i,e)
    {
        u=edges[i].u;
        v=edges[i].v;
        w=edges[i].w;
        if(dis1[u]+dis2[v]+w==L)  
        {
            Add1(u,v,w);
            h[u]=h[v]=1;
        }
    }
 
    i64 sum=cal(s,t,-1),temp;
    FOR1(i,n) 
    {
        if(i!=s&&i!=t&&h[i])
        {
            temp=sum-cal(s,t,i);
            ans[i]+=2.0*temp/sum;
        }
    }
}
 
int main()
{
    clr(head,-1); 
    RD(n,m);
    int i,u,v,w;
    FOR1(i,m)
    {
        RD(u,v,w);
        Add(u,v,w);
        Add(v,u,w);
    }
    int j;
    FOR1(i,n) FOR(j,i+1,n) deal(i,j);
    FOR1(i,n) PR(ans[i]);
}

 

 

 

你可能感兴趣的:(HDU)