NOIP提高 通訊

2021-07-16 14:20:38 字數 1422 閱讀 3866

tarjan縮點

互相到達的兩個點,就是在同乙個強連通分量裡面的點的邊權都沒有用了。

那麼明顯可以用tarjan來縮點。

需要串上n個點

那麼這個東西很像乙個最小生成樹,可惜不是。

那麼我們另闢蹊徑。

既然要保證每個點都在的出的圖中,那麼最優的方案就只有n-1條邊,那麼每個除了1號點只需要有一條邊練過來就好了。那麼肯定要保留最小的那條邊。

注意

要清空陣列tat,由於乙個陣列忘記清空,只有80分。

#include

#include

#include

#include

#include

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

#define rep(i,a) for(i=first[a];i;i=next[i])

using

namespace

std;

typedef

long

long ll;

const

int maxn=200007;

int i,j,k,l,t,n,m;

int first[maxn*2],next[maxn*2],last[maxn*2],num,chang[maxn*2];

int dfn[maxn],low[maxn],stack[maxn],df,tuan,shu[maxn],tou;

bool az[maxn],bz[maxn];

int xiao[maxn];

ll ans;

struct nodea[maxn];

void add(int x,int y,int z)

void tarjan(int x)

else

if(az[last[i]])

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

}}void dfs(int x,int y)

}}int main()

memset(bz,0,sizeof(bz));

memset(stack,0,sizeof(stack));

tarjan(1);

memset(first,0,sizeof(first));num=0;

memset(bz,0,sizeof(bz));

tou=shu[1];

fo(i,1,m)

ans=0;

memset(xiao,127,sizeof(xiao));

dfs(tou,0);

fo(i,1,tuan)if(bz[i])ans+=xiao[i];

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

}}

NOIP2016提高A組8 12 通訊

多組資料,檔案以2個0結尾。每組資料第一行,乙個整數n,表示有n個包括總部的部門 從0開始編號 然後是乙個整數m,表示有m條單向通訊線路。接下來m行,每行三個整數,xi,yi,ci,表示第i條線路從xi連向yi,花費為ci。每組資料一行,乙個整數表示達到目標的最小花費。3 3 0 1 100 1 2...

NOIP2016提高A組8 12 通訊

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

NOIP2016提高A組8 12 通訊

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