HZOI2019 B 那一天她離我而去 最小環

2022-04-14 07:11:00 字數 3290 閱讀 4108

題目大意:

那一天,我們......行啦,不要幫出題人腦補畫面了,我們來正經的題解

我們發現我們可以把與1號節點相連的所有節點取出,如果我們把最小環在1號節點處斷開,那麼最小環斷成的鏈一定是以這些節點中的某乙個節點作為起點,另乙個節點作為終點的一條路路徑。

如果不考慮時間複雜度,我們完全可以列舉作為起點的節點,每次都跑一遍最短路來更新答案。

但是上面的做法肯定會**,所以我們考慮如何降低複雜度。

我們考慮把所有的節點分為兩組,一組中的所有點作為起點,另一組中的所有點作為終點,一起跑最短路,更新答案。

如此我們發現只要我們能夠保證真正貢獻答案的一對節點會在某一次分組當中被分到不同組,我們就可以保證演算法的正確性。

因為起點與終點的編號肯定不相同,於是我們可以按照二進位制分組,列舉每個二進位制位,按照當前二進位制位的0/1情況來進行分組。

我看好像沒有人用這種方法的,其實dij就可以過,用dij求1號節點開始的最小環

別告訴我你不會求最小環。

我們列舉1號點連線的每一條邊,設起點為fr[i],終點為to[i],

先把這條邊權變成0x3f3f3f3f,跑dij,求出此時fr[i]到to[i]的最短路,再加上原來這條邊的權值就是乙個環的大小,

更新答案:ans=min(dis[to[i]]+w[i]);

就是把fr[i]和to[i]間的邊斷開後兩點間的最短路加上原來兩點間的距離取最小值

原來博主想用tarjan求邊雙,然後在1號節點所在的邊雙中跑dij,但時間並沒有下去

還有注意給邊編號從2開始,這樣i和i^1是一對雙向邊

本來一道很有思維量的題被做成了dijkstra模板(好像沒人用正解打)

#include#include#include#include#define ll long long

#define maxn 10005

#define maxm 40005

using namespace std;

ll t,n,m,ans=0x3f3f3f3f;

ll pre[maxn],tot_e=1,to[maxm<<1],nxt[maxm<<1],w[maxm<<1];

void add(ll u,ll v,ll d)

ll dis[maxn];

priority_queue< pair> q;

bool visit[maxn];

void dijkstra(ll x)

} }}int main()

for(ll i=pre[1];i;i=nxt[i])

if(ans==0x3f3f3f3f) ans=-1;

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

ans=0x3f3f3f3f;

tot_e=1;

memset(pre,0,sizeof(pre));

} return 0;

}

1 #include2 #include3 #include4 #include5

#define ll long long

6#define maxn 10005

7#define maxm 40005

8using

namespace

std;

9 ll t,n,m,ans=0x3f3f3f3f

;10 ll pre[maxn],tot_e=1,to[maxm<<1],nxt[maxm<<1],w[maxm<<1

];11

void

add(ll u,ll v,ll d)

14bool vis[maxm<<1

];15

void

dfs(ll x,ll res)22}

23for(ll i=pre[x];i;i=nxt[i])29}

30}31 ll dfn[maxn],low[maxn],dfs_order=0;32

bool is_bridge[maxm<<1

];33

void

tarjan(ll x,ll in_edge)

43else

if(i!=(in_edge^1

))44 low[x]=min(low[x],dfn[y]);45}

46}47bool

belong[maxn];

48void dfs(int

x)55}56

ll dis[maxn];

57 priority_queue< pair>q;

58bool

visit[maxn];

59void

dijkstra(ll x)74}

75}76}

77int

main()

86 dfs(1,0

);87

if(ans==0x3f3f3f3f) ans=-1

;88 printf("

%lld\n

",ans);

89 ans=0x3f3f3f3f

;90 memset(pre,0,sizeof

(pre));

91 tot_e=1

;92 }else

97for(ll i=1;i<=n;i++)

100 dfs(1

);101

for(ll i=pre[1];i;i=nxt[i])

109if(ans==0x3f3f3f3f) ans=-1

;110 printf("

%lld\n

",ans);

111 ans=0x3f3f3f3f

;112 tot_e=1,dfs_order=0

;113 memset(pre,0,sizeof

(pre));

114 memset(dfn,0,sizeof

(dfn));

115 memset(is_bridge,0,sizeof

(is_bridge));

116}

117}

118return0;

119 }

tarjan的複雜演算法

HZOI2019 A 那一天我們許下約定 dp

題目大意 讀這道題的題目讓我想起了。woc我到底在想什麼?好好寫題解,現在不是幹那個的時候!好吧,這題我交了20多次,一開始發現爆了long long,連慢速乘都用上了 但毫無改觀,2000 1000000000000 2000的資料都能過,為什麼還是30分?後來我頹了個 對於次題的題解 還是看官方...

那一天我們許下約定

那一天我們在教室裡許下約定。我至今還記得我們許下約定時的歡聲笑語。我記得她說過她喜歡吃餅乾,很在意自己體重的同時又控制不住自己。她跟我做好了約定 我拿走她所有的餅乾共 n 塊,在從今天起不超過 d 天的時間裡把所有的餅乾分次給她,每天給她的餅乾數要少於m以防止她吃太多。當然,我們的約定並不是餅乾的約...

那一天 倉央嘉措

突然想起大學那會兒,好喜歡這首詩,心。那一天,閉目在經殿香霧中,驀然聽見,你誦經中的真言 那一月,我搖動所有的經筒,不為超度,只為觸控你的指尖 那一年,磕長頭匍匐在山路,不為覲見,只為貼著你的溫暖 那一世,轉山轉水轉佛塔啊,不為修來生,只為途中與你相見 那一刻,我公升起風馬,不為祈福,只為守候你的到...