首页 > 代码库 > Codeforces Round #277.5 (Div. 2)D Unbearable Controversy of Being (暴力)

Codeforces Round #277.5 (Div. 2)D Unbearable Controversy of Being (暴力)

这道题我临场想到了枚举菱形的起点和终点,然后每次枚举起点指向的点,每个指向的点再枚举它指向的点看有没有能到终点的,有一条就把起点到终点的路径个数加1,最后ans+=C(路径总数,2)。每两个点都这么弄。但是我考虑时间复杂度n2前面的系数过大会超时,再想别的方法也没想出来。。

其实思路就是这样的,只不过时间上可以优化一下,就是用常用的两种做法不变而优化时间复杂度的方法:1.以空间换时间2.分步降维

#include <cstdio>#include <vector>using namespace std;const int maxn = 3000 + 10;bool G[maxn][maxn];vector<int> nxt[maxn];int main(){    //freopen("in.txt", "r", stdin);    int n, m;    scanf("%d%d", &n, &m);    for(int i = 0; i < m; ++i)    {        int a, b;        scanf("%d%d", &a, &b);        G[a][b] = true;        nxt[a].push_back(b);    }    int ans = 0;    for(int a = 1; a <= n; ++a)        for(int c = 1; c <= n; ++c)        {            if(a != c)            {                int r = 0;                for(int b = 0; b < nxt[a].size(); ++b)                {                    if(nxt[a][b] != a && nxt[a][b] != c && G[nxt[a][b]][c])                        r++;                }                ans += r*(r-1)/2;            }        }    printf("%d\n", ans);    return 0;}
以空间换时间
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<cmath>#include<map>#include<set>#include<vector>#include<algorithm>#include<stack>#include<queue>#include<cctype>#include<sstream>using namespace std;#define pii pair<int,int>#define LL long long intconst int eps=1e-8;const int INF=1000000000;const int maxn=3000+10;vector<int>v[maxn];int n,m,a,b,num[maxn][maxn],ans=0;int main(){    //freopen("in8.txt","r",stdin);    //freopen("out.txt","w",stdout);    scanf("%d%d",&n,&m);    for(int i=0;i<m;i++)    {        scanf("%d%d",&a,&b);        v[a].push_back(b);    }    for(int i=1;i<=n;i++)    {        int si=v[i].size();        for(int j=0;j<si;j++)        {            int t=v[i][j];            int st=v[t].size();            for(int k=0;k<st;k++)            {                num[i][v[t][k]]++;            }        }    }    for(int i=1;i<=n;i++)    {        for(int j=1;j<=n;j++)        {            if((i!=j)&&(num[i][j]>0))            {                ans+=(num[i][j]-1)*num[i][j]/2;            }        }    }    printf("%d\n",ans);    //fclose(stdin);    //fclose(stdout);    return 0;}
分步降维

 

Codeforces Round #277.5 (Div. 2)D Unbearable Controversy of Being (暴力)