HDU 1827 Summer Holiday(Tarjan縮點),hdutarjan
Problem DescriptionTo 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 162 2 2 2 2 2 2 2 2 2 2 2 1 33 22 13 42 43 55 44 66 47 47 127 88 78 910 911 10
Sample Output
3 6題意:中文#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<limits.h>typedef long long LL;using namespace std;const int INF=0x3f3f3f;#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define CLEAR( a , x ) memset ( a , x , sizeof a )const int maxn=1100;const int maxm=10000;struct node{ int u,v; int next;}e[maxm];int head[maxn],cntE;int DFN[maxn],low[maxn];int s[maxm],top,index,cnt;int belong[maxn],instack[maxn];int in[maxn],val[maxn];int tt[maxn];//tt儲存縮成的點中的最小值int n,m;void init(){ top=cntE=0; index=cnt=0; CLEAR(DFN,0); CLEAR(head,-1); CLEAR(instack,0);}void addedge(int u,int v){ e[cntE].u=u;e[cntE].v=v; e[cntE].next=head[u]; head[u]=cntE++;}void Tarjan(int u){ DFN[u]=low[u]=++index; instack[u]=1; s[top++]=u; for(int i=head[u];i!=-1;i=e[i].next) { int v=e[i].v; if(!DFN[v]) { Tarjan(v); low[u]=min(low[u],low[v]); } else if(instack[v]) low[u]=min(low[u],DFN[v]); } int v; if(DFN[u]==low[u]) { cnt++; do{ v=s[--top]; belong[v]=cnt; instack[v]=0; }while(u!=v); }}void work(){ REPF(i,1,n) if(!DFN[i]) Tarjan(i); CLEAR(in,0); CLEAR(tt,INF); REPF(i,1,n) { if(tt[belong[i]]>val[i]) tt[belong[i]]=val[i]; } REPF(k,1,n) { for(int i=head[k];i!=-1;i=e[i].next) { int v=e[i].v; if(belong[k]!=belong[v]) in[belong[v]]++; } } int ans=0; int num=0; REPF(i,1,cnt) { if(!in[i]) { num++; ans+=tt[i]; } } printf("%d %d\n",num,ans);}int main(){ int u,v; while(~scanf("%d%d",&n,&m)) { init(); for(int i=1;i<=n;i++) scanf("%d",&val[i]); for(int i=0;i<m;i++) { scanf("%d%d",&u,&v); addedge(u,v); } work(); } return 0;}
hdu1269 前向星+tarjan 不知道錯什地方更改
沒有迴圈調用