NOIP2016提高A組8 12 通訊

2021-07-16 13:47:18 字數 1634 閱讀 7882

多組資料,檔案以2個0結尾。

每組資料第一行,乙個整數n,表示有n個包括總部的部門(從0開始編號)。然後是乙個整數m,表示有m條單向通訊線路。

接下來m行,每行三個整數,xi,yi,ci,表示第i條線路從xi連向yi,花費為ci。

每組資料一行,乙個整數表示達到目標的最小花費。

3 3

0 1 100

1 2 50

0 2 100

3 3

0 1 100

1 2 50

2 1 100

2 2

0 1 50

0 1 100

0 0150

100

50 【樣例解釋】

第一組資料:總部把訊息傳給分部1,分部1再傳給分部2.總費用:100+50=150.

第二組資料:總部把訊息傳給分部1,由於分部1和分部2可以互相傳遞訊息,所以分部1可以無費用把訊息傳給2.總費用:100+0=100.

第三組資料:總部把訊息傳給分部1,最小費用為50.總費用:50.

對於10%的資料,保證m=n-1

對於另30%的資料,n ≤ 20 ,m ≤ 20

對於100%的資料,n ≤ 50000 ,m ≤ 10^5 ,ci ≤ 10^5 ,資料組數 ≤ 5

資料保證一定可以將資訊傳遞到所有部門。

如果兩個點可以互相傳訊息,也就是說兩個點在同乙個強連通分量裡面,它們免費,也就是說可以看做乙個點。

於是先tarjan求強連通分量縮成乙個點

接著對於每個點,所有連向它的邊中選最小的乙個即可,因為不管這條邊是誰連來的,所有點都是要被選的,那麼取min即可

#include

#include

#include

#include

#define fo(i,a,b) for(int i=a;i<=b;i++)

#define n 50100

#define clear(a) memset(a,0,sizeof(a))

using namespace std;

int n,m,last[n],next[n*10],to[n*10],color[n],dfn[n],low[n],tot=0,bz[n],bz2[n],s[n*10],totot=0,a[n*10][3],mi[n],mn[n];

void putin(int x,int y)

void tarjan(int x)

else if(bz2[y]==1) low[x]=min(low[x],dfn[y]);

}if(dfn[x]==low[x])

}int main()

tot=totot=0;

tarjan(0);

fo(i,1,m)

if(color[a[i][2]])

else

int ans=0;

fo(i,1,n-1) ans+=(mi[i]==2139062143)?0:mi[i];

fo(i,1,totot) ans+=(mn[i]==2139062143)?0:mn[i];

printf("%d\n",ans);

scanf("%d%d",&n,&m);

}}

NOIP2016提高A組8 12 禮物

夏川的生日就要到了。作為夏川形式上的男朋友,季堂打算給夏川買一些生日禮物。商店裡一共有種禮物。夏川每得到一種禮物,就會獲得相應喜悅值wi 每種禮物的喜悅值不能重複獲得 每次,店員會按照一定的概率pi 或者不拿出禮物 將第i種禮物拿出來。季堂每次都會將店員拿出來的禮物買下來。眾所周知,白毛切開都是黑的...

NOIP2016提高A組8 12 通訊

首先處理忽略劃分的情況,如果兩個部門可以直接或間接地相互傳遞訊息,那麼他們一定在同乙個強連通分量之中。就用tarjan縮點。所點後就變成了個有向無環圖,很容易想到,最小花費的方案數選的路線,一定只有n 1條,也就是說每個強連通分量塊的入邊只有乙個 除了0所在的強連通分量塊 那麼就每個強連通分量塊 除...

NOIP2016提高A組8 12 通訊

首先處理忽略劃分的情況,如果兩個部門可以直接或間接地相互傳遞訊息,那麼他們一定在同乙個強連通分量之中。就用tarjan縮點。所點後就變成了個有向無環圖,很容易想到,最小花費的方案數選的路線,一定只有n 1條,也就是說每個強連通分量塊的入邊只有乙個 除了0所在的強連通分量塊 那麼就每個強連通分量塊 除...