题目描述
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\n",sum); } return 0; }