大學ACM第二週心得

2022-07-09 22:39:09 字數 4222 閱讀 8409

小小分個類

這裡推薦這篇部落格:[

例:受歡迎的牛[

由題可得,受歡迎的奶牛只有可能是圖中唯一的出度為零的強連通分量中的所有奶牛,所以若出現兩個以上出度為0的強連通分量則不存在明星奶牛,因為那幾個出度為零的分量的愛慕無法傳遞出去。那唯一的分量能受到其他分量的愛慕同時在分量內相互傳遞,所以該分量中的所有奶牛都是明星。

#include#define inf 1000001

using namespace std;

int p=0,top=0,inde=0,maxn=0,block=0,n,m,sum=0;

int head[inf],aa[inf],dfn[inf],vis[inf],low[inf],book[inf],ans[inf],dis[inf];

int used[inf],deg[inf],stac[inf],x[inf],y[inf];

struct node

a[inf];

void add(int u,int v)

void tarjan(int u)

else if(book[ne])

low[u]=min(low[u],dfn[ne]);

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

}int main()

for (int i=1;i<=n;i++)

/*for (int i=1;i<=m;i++)

}*/for (int i=1;i<=n;i++) }

for (int i=1;i<=block;i++)

if (sum==1)

else printf("0");

return 0;

}

割點定義:在無向連通圖中,如果將其中乙個點以及所有連線該點的邊去掉,圖就不再連通,那麼這個點就叫做割點

可參考:[

從學tarjan的時候一直就疑惑這句**low[k]=min(low[k],dfn[u])為什麼不換成low[u]=min(low[u],low[v])

而且這個能被hack的反例也很難找,在縮點裡兩種打法都能過。但是在割點裡只要資料強一點就不行。

舉個栗子,看下這張圖:

假設按以下順序dfs,括號裡表示的是回溯的過程

0-1-2-3-0(-3-2)-4-5-2(-5-4-2)-5(-2-1-0)-3(-0)

low和dfn比較:low[0]=low[1]=low[2]=low[3]=0

low[4]=low[5]=2

low和low比較:全部都是0…

問題出在low[5]上,如果是low[5]和dfn[2]比較low[5]=2,如果是和low[2]比較,low[5]=0

當low[5]=2的時候,2判斷是割點,當low[5]=0的時候,2判斷就不是割點了。

而實際上2是割點。

這裡是模板題鏈結[

#includeusing namespace std;

int dfn[200010],low[200010],p,ans,n,m,used[200010],head[200010],inde;

struct node

e[200010];

void add(int u,int v)

void dfs(int u,int fa)

else if(v!=fa)

low[u]=min(low[u],low[v]);

} if (fa<0&&son==1) ans--,used[u]=0;

}int main()

for (int i=1;i<=n;i++)

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

for (int i=1;i<=n;i++)

return 0;

}

有三種求最短路的方法:floyd演算法比較簡單,就是暴力列舉了所有可能,將所有可能路徑找遍,就知道了兩點之間的最短路

void floyd()

需要注意的是第一層迴圈是列舉中間點

原因可以看這篇:[

一般就是指堆優化了的dijkstra

struct node

;bool operator < (node a, node b)

void dijkstar()}}

}

為什麼spfa可以處理負邊:因為在spfa中每乙個點鬆弛過後說明這個點距離更近了,所以有可能通過這個點會再次優化其他點,所以將這個點入隊再判斷一次,而dijkstra中是貪心的策略,每個點選擇之後就不再更新,如果碰到了負邊的存在就會破壞這個貪心的策略就無法處理了。

如何判斷成環:

在儲存邊時,記錄下每個點的入度,每個點入隊的時候記錄一次,如果入隊的次數大於這個點的入度,說明從某一條路進入了兩次,即該點處成環。

三種求最短路的優缺點:

#include#define ll long long

#define inf 1e10

#define n 100010

#define lson rt<<1

#define rson rt<<1|1

#define fr freopen("tset.in","r",stdin)

#define fw freopen("test.out","w",stdout)

using namespace std;

ll read()

while (ch>='0'&&ch<='9')

return x*f;

}int ch[n][2],sz[n],cnt[n],key[n],f[n],rt,tot,n;

int pd(int x)

void update(int x)

}void clear(int x)

void rotate(int x)

void spl(int x)

}void insert(int x)

int nw=rt,fa=0;

while(1)

fa=nw;nw=ch[nw][x>key[nw]];

if (nw==0)//這個值之前不存在

}}int ask1(int x)

if (!ch[rt][0]&&!ch[rt][1])

if (!ch[rt][0])

if (!ch[rt][1])

int pre=getpre(),old=rt;

spl(pre);

ch[rt][1]=ch[old][1];

f[ch[old][1]]=rt;

clear(old);

update(rt);

}int main()

if (ty==6) }}

#include#define inf 1000000000

#define ll long long

#define n 100010

#define lson rt<<1

#define rson rt<<1|1

using namespace std;

inline ll read()

while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();

return x*f;

}int ch[n][2],sz[n],cnt[n],key[n],f[n],root,tot,n,a[n],tag[n],m;

void update(int x)

int pd(int x)

void pushdown(int x)

}int build(int l,int r,int fa)

void rotate(int x)

void spl(int x,int goal)

}int ask(int x) }}

void print(int x)

int main()

print(root);

}

逆元,求逆元,判斷兩直線相交都放在了

大學ACM第八周心得

寫在前面 dp要設定好初始狀態 mle不一定是陣列,結構體之類開大了,也可能是遞迴呼叫太多記憶體 看清楚有沒有多組資料 training 2.2.2 subset sums 01揹包,總容量為 1 2 n 2 training 2.2.3 runaround numbers 我直接暴力列舉,暴力判斷...

第二週心得

學習心得入學已經第二週了,漸漸感覺到程式設計的樂趣,以及老師們的 輔導認真,班主任老師的認真負責,個人還是比較懶惰成性的 多虧了老師們的認真負責督促學習,使得第二週的學習相比較 第一周的學習更加得心應手,學到的一周比一周多,本週還新 添了就業指導課以及拓展培訓課,使我們收益良多。認識到了 更多的新層...

第二週總結ACM

這週是對上週所學的兩個演算法加以鞏固的一周,上週我學習了兩個演算法分別是 最小生成樹和並查集 這兩個演算法的簡單使用還是沒有問題的,並查集提公升中包含了乙個種類並查集,對於它我並沒有很好地掌握,下週之前爭取拿下。這週在做題中時常碰到別的演算法與該演算法結合的綜合性題目,比如洛谷中的一道藍色題目 貨車...