1. 程式人生 > >HDU-1827 Summer Holiday

HDU-1827 Summer Holiday

div std scan 過去 hdu summer map output script

To see a World in a Grain of Sand
And a Heaven in a Wild Flower,
Hold Infinity in the palm of your hand
And Eternity in an hour.
—— William Blake

聽說lcy幫大家預定了新馬泰7日遊,Wiskey真是高興的夜不能寐啊,他想著得快點把這消息告訴大家,雖然他手上有所有人的聯系方式,但是一個一個聯系過去實在太耗時間和電話費了。他知道其他人也有一些別人的聯系方式,這樣他可以通知其他人,再讓其他人幫忙通知一下別人。你能幫Wiskey計算出至少要通知多少人,至少得花多少電話費就能讓所有人都被通知到嗎?

Input多組測試數組,以EOF結束。
第一行兩個整數N和M(1<=N<=1000, 1<=M<=2000),表示人數和聯系對數。
接下一行有N個整數,表示Wiskey聯系第i個人的電話費用。
接著有M行,每行有兩個整數X,Y,表示X能聯系到Y,但是不表示Y也能聯系X。
Output輸出最小聯系人數和最小花費。
每個CASE輸出答案一行。
Sample Input
12 16
2 2 2 2 2 2 2 2 2 2 2 2 
1 3
3 2
2 1
3 4
2 4
3 5
5 4
4 6
6 4
7 4
7 12
7 8
8 7
8 9
10 9
11 10
Sample Output
3 6

求最小點基和最小權點基稞題。

①找出圖G的所有強連通分量。

②從強連通分量中找出所有的最高強連通分量。也就是縮點後入度為0的點。

③從每個最高強連通分量中任取一點,組成點集B就是一個最小點基。

從每個最高強連通分量中取權值最小的點,組成點集B就是一個最小點權基。

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <cstdio>
#include 
<string> #include <vector> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define ll long long #define file(a) freopen(a".in","r",stdin); freopen(a".out","w",stdout); inline int gi() { bool b=0; int r=0; char
c=getchar(); while(c<0 || c>9) { if(c==-) b=!b; c=getchar(); } while(c>=0 && c<=9) { r=r*10+c-0; c=getchar(); } if(b) return -r; return r; } const int inf = 1e9+7, N = 1007, M = 2007; int n,m,num,cnt,Deep,f[N],dfn[N],low[N],bl[N],V[N],C[N],rd[N]; bool b[N]; stack <int> s; struct data { int fr,nx,to; }da[M]; inline void add (int fr,int to) { da[++num].fr=fr, da[num].to=to, da[num].nx=f[fr], f[fr]=num; } inline void tarjan (int o) { int i,to; dfn[o]=low[o]=++Deep; s.push(o); b[o]=1; for (i=f[o]; i; i=da[i].nx) { to=da[i].to; if (!dfn[to]) tarjan (to), low[o]=min(low[o],low[to]); else if (b[to]) low[o]=min(low[o],dfn[to]); } if (low[o] == dfn[o]) { cnt++; do { to=s.top(); s.pop(); b[to]=0; bl[to]=cnt; V[cnt]=min(V[cnt],C[to]); } while(to != o); } } int main() { // file("HDU-1827"); int i,x,y; while (scanf ("%d%d",&n,&m) != EOF) { for (i=1; i<=n; i++) C[i]=gi(), V[i]=inf; for (i=1; i<=m; i++) { x=gi(), y=gi(); add (x,y); } for (i=1; i<=n; i++) if(!dfn[i]) tarjan (i); for (i=1; i<=num; i++) { x=bl[da[i].fr], y=bl[da[i].to]; if (x != y) rd[y]++; } x=0, y=0; for (i=1; i<=cnt; i++) if (!rd[i]) x++, y+=V[i]; printf ("%d %d\n",x,y); for (i=1; i<=n; i++) f[i]=C[i]=V[i]=dfn[i]=low[i]=bl[i]=0; for (i=1; i<=cnt; i++) rd[i]=0; for (i=1; i<=num; i++) da[i]={ 0,0,0 }; num=Deep=cnt=0; } return 0; }

歡迎在評論區提問質疑!

HDU-1827 Summer Holiday