洛谷P2194 【HXY燒情侶】

首先請容許我吐槽一下這個題面node

這個題面透露出血腥與暴力,電影院裏還藏汽油ios

因此情侶們,要是想看電影就在家裏看吧git

畢竟出來容易被燒安全

在家裏看雖然觀影效果不如在電影院裏spa

可是,code

起碼咱生命安全啥的有保障啊blog

題面get

思路:it

tarjanio

注意方案數是乘法原理

#include <cstdio>
#include <iostream>
using namespace std;
const int N = 1e6+7;
const int md = 1e9+7;
int n, head[N << 1], cnt,  w[N], m, dfn[N], low[N], tot, top, stac[N], ans, minn, sum = 1, geshu;
bool vis[N];
struct node {
    int nxt, to;
}e[N << 1];
int read() {
    int s = 0, w = 1;
    char ch = getchar();
    while(!isdigit(ch)) {if(ch == '-') w = -1; ch = getchar();}
    while(isdigit(ch)) {s = s * 10 + ch - '0'; ch = getchar();}
    return s * w;
}
void add(int x, int y) {
    e[++cnt].nxt = head[x];
    e[cnt].to = y;
    head[x] = cnt;
}
void tarjan(int u) {
    dfn[u] = low[u] = ++tot, stac[++top] = u, vis[u] = 1;
    for(int i = head[u]; i; i = e[i].nxt) {
        int v = e[i].to;
        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(vis[v]) low[u] = min(low[u], dfn[v]); 
    }
    if(dfn[u] == low[u]) {
        geshu = 0,     minn = 0x3f3f3f3f;
        while(stac[top] != u) {
            vis[stac[top]] = 0;
            if(w[stac[top]] < minn) minn = w[stac[top]], geshu = 0;
            if(w[stac[top--]] == minn) geshu++;
        }
        top--, vis[u] = 0;
        if(w[u] < minn) minn = w[u], geshu = 1;
        else if(w[u] == minn) geshu++;
        ans += minn;
        sum = (sum * geshu) % md;
    }
} 
int main() {
    n = read();
    for(int i = 1; i <= n; i++) w[i] = read();
    m = read();
    for(int i = 1, x, y; i <= m; i++) {
        x = read(), y = read();
        add(x, y);
    }
    for(int i = 1; i <= n; i++) 
        if(!dfn[i]) tarjan(i);
    printf("%d %d\n", ans, sum);
    return 0;
}

謝謝收看, 祝身體健康!

相關文章
相關標籤/搜索