多組資料,檔案以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所在的強連通分量塊 那麼就每個強連通分量塊 除...