HXY燒情侶
阿新 • • 發佈:2019-02-28
template 方案 efi 復制 () 整數 orange pre 進行
題目描述
眾所周知,HXY已經加入了FFF團。現在她要開始喜(sang)聞(xin)樂(bing)見(kuang)地燒情侶了。這裏有n座電影院,n對情侶分別在每座電影院裏,然後電影院裏都有汽油,但是要使用它需要一定的費用。m條單向通道連接相鄰的兩對情侶所在電影院。然後HXY有個絕技,如果她能從一個點開始燒,最後回到這個點,那麽燒這條回路上的情侶的費用只需要該點的汽油費即可。並且每對情侶只需燒一遍,電影院可以重復去。然後她想花盡可能少的費用燒掉所有的情侶。問最少需要多少費用,並且當費用最少時的方案數是多少?由於方案數可能過大,所以請輸出方案數對1e9+7取模的結果。
(註:這裏HXY每次可以從任何一個點開始走回路。就是說一個回路走完了,下一個開始位置可以任選。所以說不存在燒不了所有情侶的情況,即使圖不連通,HXY自行選擇頂點進行燒情侶行動。且走過的道路可以重復走。)
輸入輸出格式
輸入格式:
第一行,一個整數n。
第二行,n個整數,表示n個情侶所在點的汽油費。
第三行,一個整數m。
接下來m行,每行兩個整數xi,yi,表示從點xi可以走到yi。
輸出格式:
一行,兩個整數,第一個數是最少費用,第二個數是最少費用時的方案數對1e9+7取模
輸入輸出樣例
輸入樣例#1: 復制3 1 2 3 3 1 2 2 3 3 2輸出樣例#1: 復制
3 1輸入樣例#2: 復制
3 10 20 10 4 1 2 1 3 3 1 2 1輸出樣例#2: 復制
10 2
說明
數據範圍:
對於30%的數據,1<=n,m<=20;
對於10%的數據,保證不存在回路。
對於100%的數據,1<=n<=100000,1<=m<=300000。所有輸入數據保證不超過10^9。
#include<bits/stdc++.h> #define REP(i, a, b) for(int i = (a); i <= (b); ++ i) #define REP(j, a, b) for(int j = (a); j <= (b); ++ j) #define PER(i, a, b) for(int i = (a); i >= (b); -- i) usingnamespace std; const int maxn=5e5+5; const int mod=1e9+7; template <class T> inline void rd(T &ret){ char c; ret = 0; while ((c = getchar()) < ‘0‘ || c > ‘9‘); while (c >= ‘0‘ && c <= ‘9‘){ ret = ret * 10 + (c - ‘0‘), c = getchar(); } } struct node{int to,nx;}p[maxn]; int vis[maxn],val[maxn],head[maxn],n,m,tot,cnt,ans,fn,dfn[maxn],low[maxn],my; void addedge(int u,int v){ p[++tot].to=v,p[tot].nx=head[u],head[u]=tot; } vector<int>v[maxn]; stack<int>sk; void tarjan(int s){ dfn[s]=low[s]=++cnt; vis[s]=1; sk.push(s); for(int i=head[s];i;i=p[i].nx){ int to=p[i].to; if(!dfn[to]){ tarjan(to); low[s]=min(low[s],low[to]); } else if(vis[to]) low[s]=min(low[s],dfn[to]); } if(dfn[s]==low[s]){ int cur; ++my; do{ cur=sk.top(); sk.pop(); vis[cur]=0; v[my].push_back(cur); }while(cur!=s); } } int main() { rd(n); fn=1; REP(i,1,n)rd(val[i]); rd(m); REP(i,1,m){ int u,v; rd(u),rd(v); addedge(u,v); } REP(i,1,n){ if(!dfn[i])tarjan(i); } REP(i,1,my){ int cur=v[i].size(),tmp=0,minn=mod; for(int j=0;j<cur;j++){ if(minn>val[v[i][j]]){ minn=val[v[i][j]]; tmp=1; } else if(minn==val[v[i][j]]) tmp++; } ans+=minn; fn=(fn%mod*tmp%mod)%mod; } cout<<ans<<‘ ‘<<fn<<endl; return 0; }
HXY燒情侶