1. 程式人生 > >HXY燒情侶

HXY燒情侶

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)
using
namespace 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燒情侶