NEU 1685: All Pair Shortest Path

题目描述

Bobo has a directed graph G with n vertex labeled by 1,2,3,..n.

Let D(i,j) be the number of edges from vertex i to vertex j on the shortest path.

If the shortest path does not exist,then D(i,j)=n.

Bobo would like to find the sum of  D(i,j)*D(i,j) for all 1<=i<=n and 1<=j<=n.

输入

There are no more than 5 test cases.

The first line contains an integer n(1<=n<=1000).

The i-th of the following n lines contains n integers g(i,1),g(i,2),..g(i,n).

If there is an edge from i to j,then g(i,j)=1,otherwise g(i,j)=0;

输出

An integer denotes the sum of D(i,j)*D(i,j) for all 1<=i<=n and 1<=j<=n.

样例输入

3
010
001
100
2
10
01

样例输出

15
8
题意就是求所有D(i,j)*D(i,j)的和。D(i,j)代表i j之间的最短路径。
正常的想法肯定是 bfs求出任意两点之间的最短路径 但这样做的时间复杂度大概n^3 会超时。
得优化。用set维护未访问的点 因为set的删除 插入的操作都是logn 而n最大是1000。所以总体的时间复杂度是 常数*n^2
/* ***********************************************
Author        :guanjun
Created Time  :2016/3/21 16:44:25
File Name     :neu1685.cpp
************************************************ */
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <iomanip>
#include <list>
#include <deque>
#include <stack>
#define ull unsigned long long
#define ll long long
#define mod 90001
#define INF 0x3f3f3f3f
#define maxn 1010
#define cle(a) memset(a,0,sizeof(a))
const ull inf = 1LL << 61;
const double eps=1e-5;
using namespace std;
priority_queue<int,vector<int>,greater<int> >pq;
struct Node{
    int x,y;
};
struct cmp{
    bool operator()(Node a,Node b){
        if(a.x==b.x) return a.y> b.y;
        return a.x>b.x;
    }
};

bool cmp(int a,int b){
    return a>b;
}
int n;
char mp[maxn][maxn];
int vis[maxn];
int dis[maxn];
ll sum=0;
set<int>s;
set<int>::iterator it;
void solve(){
    cle(dis);
    s.clear();
    int cnt=0;
    queue<int>q;
    for(int i=1;i<=n;i++){
        q.push(i);
        for(int j=1;j<=n;j++){
            if(i==j)continue;
            if(mp[i][j]=='1')dis[j]=1,q.push(j);
            else s.insert(j);
        }
        //cout<<"s "<<s.size()<<endl;
        while(!q.empty()){
            int x=q.front();q.pop();
            cnt=0;
            for(it=s.begin();it!=s.end();it++){
                if(mp[x][*it]=='1'){
                    q.push(*it);
                    dis[*it]=dis[x]+1;
                    vis[++cnt]=*it;
                }
            }
            for(int j=1;j<=cnt;j++)s.erase(vis[j]);
        }
        for(int j=1;j<=n;j++){
            if(i==j)continue;
            else{
                if(dis[j]>0)sum+=dis[j]*dis[j];
                else sum+=n*n;
            }
        }
        cle(dis);
    }
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    //freopen("out.txt","w",stdout);
    while(cin>>n){
        sum=0;
        for(int i=1;i<=n;i++){
            scanf("%s",mp[i]+1);
        }
        /*
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++)
                printf("%c%c",mp[i][j],j==n?10:' ');
        }*/
        solve();
        printf("%lld
",sum);
    }
    return 0;
}


原文地址:https://www.cnblogs.com/pk28/p/5305585.html