很久很久以前有乙個國家,這個國家有 n 個城市,城市由 1,2,3,…,,n 標號,城市間有 m 條雙向道路,每條道路都有兩個屬性 g 和 s ,兩個城市間可能有多條道路,並且可能存在將某一城市與其自身連線起來的道路。後來由於戰爭的原因,國王不得不下令減小花費從而關閉一些道路,但是必須要保證任意兩個城市相互可達。
道路花費的計算公式為 wg*max+ws*max,其中 wg 和 ws 是給定的值。國王想要在滿足連通性的前提下使這個花費最小,現在需要你計算出這個花費。
第一行包含兩個正整數 n 和 m 。
第二行包含兩個正整數 wg 和 ws 。
後面的 m 行每行描述一條道路,包含四個正整數 u,v,g,s,分別表示道路連線的兩個城市以及道路的兩個屬性。
輸出乙個整數,表示最小花費。若無論如何不能滿足連通性,輸出 -1 。
輸入
3 3輸出2 1
1 2 10 15
1 2 4 20
1 3 5 1
30【資料規模與約定】
對於 10% 的資料,n≤10;m≤20;
對於 30% 的資料,n≤100;m≤1000;
對於 50% 的資料,n≤200;m≤5000;
對於 100% 的資料,n≤400;m≤50000;wg,ws,g,s≤1000000000。
解析:按照g公升序排序。 維護乙個n-1條邊的邊集,是上乙個建造的最小生成樹的邊集。 從前往後列舉maxg,把這條邊按照s用插入排序插入到當前n-1條邊的集合中。 在這樣的n條邊的集合中建造一顆最小生成樹,最後再把用到的邊存到邊集中(就是將沒用到的刪去),從而維護了乙個n-1的邊集。 剛才所說的邊集其實就是維護的一棵最小生成樹。
時間複雜度≈o(m*n)。
因為最小生成樹的性質:在當前的最小生成樹中插入一條邊,構成了環,把環中最長的邊刪去就是新的最小生成樹。
**:
#include #include #include #include #include #include using namespace std;
const int max=50010;
long long ans=1e18,wg,ws;
int n,m,size,tot;
int father[410],p[410];
struct shu;
shu edge[max];
inline int get_int()
for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
return x*f;
}inline int mx(int x,int y)
inline long long mn(long long x,long long y)
inline int getfather(int v)
inline bool comp(const shu &a,const shu &b)
inline bool check(int num)
else break;
} int flag=0;
for(int i=2;i<=n;i++) if(getfather(i) != getfather(1))
if(flag) return 0;
else
}int main()
sort(edge+1,edge+size+1,comp);
int tot = 0;
for(int i=1;i<=size;i++)
if(sum==n-1) break;
}if(sum == n-1) ans = mn(ans,maxx * ws + edge[i].g * wg);
tot = sum;
} if(ans == 1e18) cout<<"-1\n";
else cout
}
noip模擬賽 保留道路
問題描述 很久很久以前有乙個國家,這個國家有n個城市,城市由1,2,3,n標號,城市間有m條雙向道路,每條道路都有兩個屬性g和s,兩個城市間可能有多條道路,並且可能存在將某一城市與其自身連線起來的道路。後來由於戰爭的原因,國王不得不下令減小花費從而關閉一些道路,但是必須要保證任意兩個城市相互可達。道...
noip模擬賽 道路分組
分析 因為每一組編號都是連續的嘛,所以能分成一組的盡量分,每次加邊後dfs判斷一下1和n是否連通.有向圖的判連通沒有什麼很快的方法,特別注意,並查集是錯的!這個演算法可以得到60分.事實上每一次都不需要從點1開始dfs,因為之前很多點都遍歷到了,再從1開始會重複.如果新加的一條邊的起點沒有被訪問過,...
noip尋找道路
在有向圖g 中,每條邊的長度均為1 現給定起點和終點,請你在圖中找一條從起點到終點的路徑,該路徑滿足以下條件 1 路徑上的所有點的出邊所指向的點都直接或間接與終點連通。2 在滿足條件1 的情況下使路徑最短。注意 圖g 中可能存在重邊和自環,題目保證終點沒有出邊。請你輸出符合條件的路徑的長度。輸入格式...