嘘~ 正在从服务器偷取页面 . . .

CF427C Checkposts 题解


CF427C Checkposts 题解

题目链接:CF427C Checkposts

题意

懒得贴翻译,那个翻译太烂了

Your city has $ n $ junctions. There are $ m $ one-way roads between the junctions. As a mayor of the city, you have to ensure the security of all the junctions.

To ensure the security, you have to build some police checkposts. Checkposts can only be built in a junction. A checkpost at junction $ i $ can protect junction $ j $ if either $ i=j $ or the police patrol car can go to $ j $ from $ i $ and then come back to $ i $ .

Building checkposts costs some money. As some areas of the city are more expensive than others, building checkpost at some junctions might cost more money than other junctions.

You have to determine the minimum possible money needed to ensure the security of all the junctions. Also you have to find the number of ways to ensure the security in minimum price and in addition in minimum number of checkposts. Two ways are different if any of the junctions contains a checkpost in one of them and do not contain in the other.

不难发现,一个强连通分量内的答案就是最小的那个花费

而这个强连通分量里的方案数就是和最小花费相等的结点数

然后求个强连通分量,乘法原理搞一搞就好了

时间复杂度 \(O(n + m)\)

代码:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iomanip>
#include <random>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
#define N (int)(1e5+15)

const int p=1e9+7;
vector<int> g1[N],g2[N];
int n,m,idx,scnt;
int sz[N],val[N],dfn[N],scc[N],mn[N],vis[N];
void addEdge1(int u,int v)
{
    g1[u].push_back(v);
    g2[v].push_back(u);
}
void dfs1(int u)
{
    vis[u]=1;
    for(int v : g1[u])
        if(!vis[v]) dfs1(v);
    dfn[++idx]=u;
}
void dfs2(int u,int id)
{
    scc[u]=id;
    mn[id]=min(mn[id],val[u]);
    for(int v : g2[u])
        if(!scc[v]) dfs2(v,id);
}
void kosaraju()
{
    for(int i=1; i<=n; i++)
        if(!vis[i]) dfs1(i);
    scnt=0;
    for(int i=n; i>=1; i--)
        if(!scc[dfn[i]])
        {
            ++scnt;
            dfs2(dfn[i],scnt);
        }
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    // freopen("check.in","r",stdin);
    // freopen("check.out","w",stdout);
    cin >> n;
    for(int i=1; i<=n; i++)
        cin >> val[i],mn[i]=INF;
    cin >> m;
    for(int i=1,u,v; i<=m; i++)
    {
        cin >> u >> v;
        addEdge1(u,v);
    }
    kosaraju();
    for(int i=1; i<=n; i++)
        if(val[i]==mn[scc[i]])++sz[scc[i]];
    int ans1=0,ans2=1;
    for(int i=1; i<=scnt; i++)
        ans1+=mn[i],ans2=ans2*sz[i]%p;
    cout << ans1 << ' ' << ans2 << '\n';
    return 0;
}

文章作者: q779
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 q779 !
评论
  目录