标签:数据 iostream bsp ++ tchar amp reg span ted
众所周知,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取模
数据范围:
对于30%的数据,1<=n,m<=20;
对于10%的数据,保证不存在回路。
对于100%的数据,1<=n<=100000,1<=m<=300000。所有输入数据保证不超过10^9。
闲话:
烧情侣???记得带我一个啊!
分析:
本题题面中的走回路告诉了我们这题的算法:缩点!至于答案我们可以开一个数组进行存储,最后统一求解。
CODE:
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 const int M=2222222; 8 const int MOD=1000000007; 9 int n,m,tot,cnt,k; 10 int vis[M],low[M],maxn[M],dfn[M],to[M],head[M],nxt[M],v[M],connected[M],stack[M],ways[M]; 11 void add(int u,int v){ 12 nxt[++tot]=head[u];head[u]=tot; 13 to[tot]=v;return; 14 } 15 void tarjan(int x){ 16 low[x]=dfn[x]=++tot;vis[x]=1;stack[++stack[0]]=x; 17 for (int i=head[x];i;i=nxt[i]){ 18 if (!dfn[to[i]]){ 19 tarjan(to[i]); 20 low[x]=min(low[x],low[to[i]]); 21 } 22 else if (vis[to[i]]) low[x]=min(low[x],dfn[to[i]]); 23 } 24 if (low[x]==dfn[x]){ 25 maxn[++k]=2000000000; 26 while (stack[stack[0]]!=x){ 27 connected[stack[stack[0]]]=k;vis[stack[stack[0]]]=0; 28 maxn[k]=min(maxn[k],v[stack[stack[0]]]); 29 stack[0]--; 30 } 31 connected[stack[stack[0]]]=k;maxn[k]=min(maxn[k],v[stack[stack[0]]]); 32 vis[stack[stack[0]]]=0;stack[0]--; 33 } 34 return; 35 } 36 int fr(){ 37 int ans=0,f=1; 38 char c=getchar(); 39 while (c<‘0‘||c>‘9‘){if (c==‘-‘) f=-1;c=getchar();} 40 while (c>=‘0‘&&c<=‘9‘){ans=(ans<<1)+(ans<<3)+(c^48);c=getchar();} 41 if (f) return ans;return -ans; 42 } 43 int main(){ 44 n=fr(); 45 for (int i=1;i<=n;i++) v[i]=fr(); 46 m=fr(); 47 for (int i=1;i<=m;i++){ 48 int x=fr(),y=fr(); 49 add(x,y); 50 } 51 long long ans=0; 52 for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i); 53 for (int i=1;i<=k;i++) ans+=maxn[i]; 54 cout<<ans<<" ";ans=1; 55 for (int i=1;i<=n;i++) 56 if (v[i]==maxn[connected[i]]) ways[connected[i]]++; 57 for (int i=1;i<=k;i++) ans=ans*ways[i]%MOD; 58 cout<<ans; 59 return 0; 60 }
标签:数据 iostream bsp ++ tchar amp reg span ted
原文地址:https://www.cnblogs.com/kanchuang/p/11156580.html