琐碎知识

cin/scanf  制表符就结束(" " "\n".....)

gets(char a[]) ->一整行 只能char   ==   cin.getline(a,length)

string 不可以 用 scanf  且 不可以用 cin>>s+1,但可以cin>>

char  scanf  char s+1 /cin>>s+1

换行用 getchar()/cin.ignore

char s[][];   -> s[][][1--n] 具体的单个字符

scanf("%s ",s[][]) -> 一整个字符串(以第一个非空格符(” “,”\n“,制表符)开始 第一个空格符结束)

scanf("%c",&s1) -> 单个字符->放到单个存储空间

scanf("%s ",s[][]+1) -> 一整个字符串  从下标为一开始记录  strlen(s[][])=len 因为 [0]空

#include<iostream>
using namespace std;
int main()
{
    cout << "请在下方输入一个数据:\n";
    cout << "________________\r";
    int a;
    cin>>a;
    cout<<"刚刚输入的是:"<<a;
    return 0;
}

请在下方输入一个数据:
33333424________
刚刚输入的是:33333424
'\r'作用
     代码题经常遇到有多个样例输入的情况,如果输入就处理不好更别说解题了。输入输出也是学习C++容易忽视的地方,简单了解cin cout是无法搞定批量等复杂输入输出情况的。

1.直接使用while(cin)

    int x;

    while(cin>>x){

            ……

    }

        许多代码平台中这样就能够处理批量数据了,但是如果在本地自己调试时会发现无法结束,这是因为:

        cin>>是带有返回值的。大多数情况下返回值为cin本身,只有遇到EOF时返回0。也就是说上面的写法可以一直获取输入,直到遇到EOF停止。有帖子说EOF在win下是ctrl+z,linux下是ctrl+d。我在windos中使用CLion输入ctrl+z无效,反倒是直接输入EOF这个字符串可以停止,可能和具体的IDE有关。

        如果想要更加便捷,键入回车结束呢?普通的cin>>会自动舍弃空格和换行符,要用其他的方式。

2.回车结束

    int x;

    while(cin>>x){

            ……

            if(cin.get()== '\n') break;

    }

        注意,cin.get()的判断要在循环的最后,如果放在循环的开始,最后一个输入就被吃掉了。cin.get()是用于读取char的,并不会舍弃换行符,所以可以读取到换行符并进行判断。

3.cin和cin.get()的联合使用

        cin和cin.get()联合使用时常容易出现错误,原因在于cin会忽略空格回车而get不会。例如在下面的输入情况中:

    10 10
    AAAAAADROW
    WORDBBBBBB
    OCCCWCCCCC
    RFFFFOFFFF
    DHHHHHRHHH
    ZWZVVVVDID
    ZOZVXXDKIR
    ZRZVXRXKIO
    ZDZVOXXKIW
    ZZZWXXXKIK
    WORD

        在cin>>读入第一行的两个数字后,再想用cin.get()读入后面的字符时,要先用一个cin.get()吃掉第一行末尾的换行符。读入字符数组时也要注意每一行末尾使用cin.get()吃掉换行符,大致代码如下:

    cin >> m >> n;

    cin.get();

    vector<vector<char>>vec(m, vector<char>(n));

    for (int row = 0; row < m; row++) {

            for (int col = 0; col < n; col++) {

                    vec[row][col] = cin.get();

            }

            cin.get();

    }

    string tar;

    cin >> tar;
while cin>>

scanf 读取字符串以后,会有一个换行符号\n存在输入缓冲区中,因此需要用scanf("%*c”);// cin.ignore()->吃掉换行

清理输入缓冲区中第一个字符,也就是上次遗留下的\n

cin   \n ->为了将s送入缓冲区,但是cin是不读入换行符的,所以换行符没有读入。所以当:

如果想直接使用scanf输入string类型,会报错。应该使用下面的方法:

string s;   getline(cin,s);

string s;   len =s.length();   s[1--n] 单个字符

string xx="1234567";  
if(xx.find("1")!=xx.npos)  //exist
cout<<xx.find("1")<<endl;  //-> 0
if(xx.find("0")==xx.npos) cout<<"ERROR"<<endl;

s2=s1.substr(start,length):从指定的 start 位置开始截取字符串,length 指定要截
 

一定要记住如果要把一个char a[20]清零,一定是 memset(a,0,20*sizeof(char));

一 二维整型数组直接利用 memset() 函数初始化时,只能初始化为 0 或 -1 ,不能是 1

(按字节 汇编语言 初始化)否则将会被设为随机值。(但memset  0x7f/0x3f3f3f3f  都可以)

fill(a,a+length,val)->val 任意值
一 二维 char 型数组利用 memset() 函数初始化时不受限制,可以初始化任意字符。

memset(buffer,'*',strlen(buffer));/ sizeof(char)*4....

 

vector<int> q;   cmp(int,int){ return a<b ;}

q.push_back(1); //->q.emplace_back(1);//只能加一个

q.emplace(q.begin(),2);//-> 2 1

int /<vector>/...type
sort(a,a+n)  / sort(a.begin(),a.end(),cmp);   //若数组无序要 排序先
int cnt=unique(a,a+n)-a;  -> cnt=unique(a.begin(),a.end())-a.begin();  //长度
for(int i=0;i<cnt;i++) cout<<a[i];  -> for(int i=0;i<n;i++) cout<<a[i];   //1234 78888899...

 

set<char> st;     char ch;
st.insert(ch);

for(set<char>::iterator it =st.begin(); it!=st.end();it++) cout<<*it<<'\n';

 

/*

*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string.h>
//#include<queue>
//#include<vector>
//#include<bits/stdc++.h>
#define ll long long;
#define ddd printf("-----------------------\n");
using namespace std;
typedef pair<int,int> pii;
const int maxn=1e1 +10;
const int mod=998244353;
const int inf=0x3f3f3f3f;

#define l first
#define r second
pii a[maxn];


int main()
{
    ios::sync_with_stdio(false);

    for(int i=1;i<=5;i++)    cin>>a[i].l>>a[i].r;
    for(int i=1;i<=5;i++) cout<<a[i].first<<a[i].second<<'\n';
    
    return 0;
}
pair 要用 typedef pair<> pii

 

for(map<int,int>::iterator it=a.begin();it!=a.end();it++)  ans+=it->second;

map<int, int> m // <=1e9 ~= 2^30

map<int,int>/<string,int>....  a;     //-> a[int]++;

a[int]=int  /  a[string]=int;

map.find(key) !=map.end() 

map.erase(key/ [st,ed) );

map.size() 

map.clear()

 

priority_queue< int ,vector<int>,greater<int> >q; //- -> +

q.push(); q.top();q.pop();

 一个 deque -> 64MB

 

 int a[5] = { 1,2,3,4,5 };
 int *p = lower_bound(a, a + 5, 3);// >=

a[i].l=lower_bound(lx+1,lx+1+cnt,a[i].l)-lx;  // ->
 cout << "*p = " << *p << endl;//return val, if no *p lower_bound exceed

#include<cstdio>
#include<iostream>
#include<algorithm>
//#include<queue>
//#include<vector>
#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------------\n");
using namespace std;
const int maxn=1e1 ;

int main()
{
    ios::sync_with_stdio(false);
    
    int a[5]={0,1,2,4,5};
    cout<<lower_bound(a,a+5,3)-a<<endl<<*lower_bound(a,a+5,3)<<endl;//3 4
    ///////////
    vector<int> st={0,1,4,2,5};//0 1 2 4 5
    sort(st.begin(),st.end(),greater());
    for(vector<int>::iterator it=st.begin();it!=st.end();it++) cout<<*it<<endl;//5 4 2 1 0
    ///////////
    vector<int>::iterator it1=lower_bound(st.begin(),st.end(),3);
    cout<<it1-st.begin()<<endl;//3
    cout<<st[it1-st.begin()]<<endl;//4
    cout<<*it1<<endl;//4
    
    return 0;
}
lower_bound详细用法

 


reverse(st,ed)->开头+结尾

int a[] -> reverse(a,a+n)/reverse(a+1+n,a+1+n)

string s="123"; reverse(s.begin(),s.end()) ->321  cout<<s<<endl;

vector<int> s={0,1,2,3}; reverse(s.begin(),s.end()) ->3210  cout<<s[i]<<endl;

char ch[]="asdfasdf"; reverse(ch,ch+strlen(ch)-1); cout<<ch[i];

 


 

int   -2^31 ~ +2^31

long long -2^64 ~+2^64

 byte  字节 = 8bit 比特

kb =1024b  b-> kb->mb->g->t>p

 

大数据时,先定义 大数据 再 小数据

long long 一维 <=1e19  ~=2^63

开int型变量的一维数组最多是3e7,long long型 1e9 ,char型1亿左右

二位 2 万 []*[]<=400000000  or-> exceed

一数字 -> 一字节

1s -> 1e8

 

 LONG_LONG_MAX

0x3f3f3f3f 8位

 

int read()
{
    int res=0,f=1; char ch=getchar();
    while(isdigit(ch)==0){
        if(ch=='-') f=-1; 
        ch=getchar();
    }
    while(isdigit(ch)){
        res=res*10+ch-'0';
        ch=getchar();
    }
    return f*res;
}

ll read()//读入优化(似乎不加会T两个点w) 
{
    ll sum=0,fg=1;
    char c=getchar();
    while(c < '0' || c > '9')
    {
        if(c=='-') fg=-1;//如果读到负号则记录 
        c=getchar();
    }
    while(c >='0' && c <='9')
    {
        sum=((sum*10)+c-'0')%p;
        //注意因为A[]可能很大,所以读入时就要进行取模操作 
        c=getchar();
    }
    return sum*fg;
    //如果是负数(fg==-1,即读到了负号)那么返回的值为负数 
}
void print(ll x)//输出优化(这个可以不加qwq) 
{
    if(x<0)
    {
        putchar('-');
        x=-x;
    }
    if(x>9)//or 0-
    {
        print(x/10);
    }
    putchar(x%10+'0');
e

read+print
View Code

 

inline __int128 read()
{
    __int128 s=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0' && ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
    return s*w;
}
inline __int128 max(__int128 x,__int128 y){return x>y ? x : y;}
inline __int128 min(__int128 x,__int128 y){return x<y ? x : y;}
inline __int128 abss(__int128 x)   //abs不知道用algorithm会不会出锅
{
    if(x>=0)return x;
    return -x;
}
void print(__int128 x){
    if(x<0) putchar('-'),x=-x;
    if(x==0) return;
    if(x>9) print(x/10);
    putchar(x%10+'0');
}
_int128 read+print

print+read

ll read()//读入优化(似乎不加会T两个点w) 
{
    ll sum=0,fg=1;
    char c=getchar();
    while(c < '0' || c > '9')
    {
        if(c=='-') fg=-1;//如果读到负号则记录 
        c=getchar();
    }
    while(c >='0' && c <='9')
    {
        sum=((sum*10)+c-'0')%p;
        //注意因为A[]可能很大,所以读入时就要进行取模操作 
        c=getchar();
    }
    return sum*fg;
    //如果是负数(fg==-1,即读到了负号)那么返回的值为负数 
}
void print(ll x)//输出优化(这个可以不加qwq) 
{
    if(x<0)
    {
        putchar('-');
        x=-x;
    }
    if(x>9)//or 0-
    {
        print(x/10);
    }
    putchar(x%10+'0');

 

 

double a=2.3434;

cout<<round(a)<<endl; //四舍五入

cout<<ceil(a)<<endl;//向上取整

cout<<floor(a)<<endl;//向下取整

 

ll res=1LL *...   ->确切的数 1,1423421,->int

double  res= 1.0 *....

 

||   或  只要有1 就是1

&  按位与 全是 1 才是 1

^ 相同为 0 不同为1

 取反操作 每一位都取反including 符号位

反码->正数+0 不变 / 负数符号位不变 其他取反

补码->正数+0 不变 / 负数符号位不变 其他取反补码 +1 -》即 负数是其反码+1

 

 

 

[+0]=[0000 0000]原=[0000 0000]反
[-0]=[1000 0000]原=[1111 1111]反
作者:IT可乐
链接:https://www.imooc.com/article/21360
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作
[+0]=[0000 0000]原=[0000 0000]反
[-0]=[1000 0000]原=[1111 1111]反
作者:IT可乐
链接:https://www.imooc.com/article/21360
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作

运算过程中 判断句,sqrt()。。都需要时间

 

常见质数 31 47 1997 2003 2017 2027 (1e9+7  1e9+9  孪生素数) 1e6+5 (1e6+3  1e6+9)


 

当数量 过大时 <=1e3 ~  可以 否则 不要加函数

struct node
{
    int ux,uy,dx,dy,use;
    void add(int x,int y)
    {
        if(use==0)
        {
            ux=x,dx=x,uy=y,dy=y;
            use=1;
        }
        else
        {
            if(x<ux) ux=x;  
            if(x>dx) dx=x;
            if(y>uy) uy=y;  
            if(y<dy) dy=y;
        }
    }
    int in_node(int x,int y){
        if(use==0) return 0;
        if(x<ux||x>dx||y<dy||y>uy) return 0;
        return 1;
    }
    int get(){
        return (dx-ux)*(uy-dy);
    }
    int cross(struct node u){
        if(in_node(u.ux,u.uy)||in_node(u.ux,u.dy)||in_node(u.dx,u.uy)||in_node(u.dx,u.dy)) return 1;
        return 0;
    }
}g[5];

int if_cross(){
    for(int i=1;i<=k;i++)
        for(int j=i+1;j<=k;j++)
            if( g[i].cross(g[j]) || g[j].cross(g[i]) ) return 1;
    return 0;
}

void dfs(int area,int cur)
{
    if(area>=ans) return ;
    if(cur==n+1)
    {
        if(if_cross()==0&&area<ans) ans=area;
        return ;
    }
    for(int i=1;i<=k;i++)
    {
        struct node t;
        t=g[i]; g[i].add(x[cur],y[cur]);
        dfs(area-t.get()+g[i].get(),cur+1);
        g[i]=t;
    }
}
struct node

struct node

{

 int use;
 bool fuc(struct node u)

{  
  if(!use||!u.use) return 0;

}

}

struct node u;

struct node{
bool operator<(const node& a)const{
  return score==a.score ?  num<a.num :score >a.score;}//a. 在右

 }

//num<a.num ++ priority 相反 要num>a.num 这样才能 从小到大出队

 

include<ctime>

clock_t   st,ed;

st=clock()

......code

ed=clock()

cout<<(double)(ed-st)/CLOCKS_PER_SECOND<<endl;
clock

 


 二分 右偏 <=x的最大值 lft<rt mid=l+r+1>>1; rt=mid-1  l=mid  /左偏 >=x的最小值  lft<rt  mid=l+r>>1; lft=mid+1 r=mid   / 准确值 lft<=rt lf=mid+1,rt=mid-1

https://blog.csdn.net/d891320478/article/details/8303072

#include<cstdio>
#include<bits/stdc++.h>
using namespace std;

const int maxn=1e6+5,base=31;

int n,m;
char a[maxn],b[maxn];
int power[maxn]={1},tmp_sum,sum[maxn];

void init()
{
    cin>>a+1>>b+1;//
    n=strlen(a+1),m=strlen(b+1);
    
    for(int i=1;i<=n;i++) power[i]=power[i-1]*base;
    
    for(int i=1;i<=m;i++) tmp_sum=tmp_sum*base+(b[i]-'a');
    
    for(int i=1;i<=n;i++) sum[i]=sum[i-1]*base+(a[i]-'a');
}
void solve()
{
    int ans=0;
    for(int i=0;i<=n-m;i++)
        if(tmp_sum==sum[i+m]-sum[i]*power[m]) ans++;
        
    cout<<ans<<endl;
    
}
int main()
{
    init();
    solve();
    
    return 0;
}
HASH 匹配串是否与模式串字串 相等
#include<cstdio>
#include<bits/stdc++.h>
using namespace std;

#define ll long long

const int maxn=3e6+5,b1=31,b2=47,mod1=1e6+3,mod2=1e6+9;//

int n;
int head[mod1],to[maxn<<1],nxt[maxn],tot=0;

void add(int a,int b)
{
    to[++tot]=b;nxt[tot]=head[a];head[a]=tot;
}
bool query(int a,int b)
{
    for(int i=head[a];i&&~i;i=nxt[i])
    {
        if(to[i]==b) return true;
    }
    return false;
}

void init()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        char op[10],name[210];
        
        cin>>op+1; cin.getline(name,210);//
        
        int len=strlen(name),sum1=0,sum2=0;
        
        for(int j=0;j<len;j++)//
        {
            sum1=(sum1*b1+name[j])%mod1;//
            sum2=(sum2*b2+name[j])%mod2;
        }
        
        if(op[1]=='a')
        {
           add(sum1,sum2); 
        }
        else 
        {
            if(query(sum1,sum2)) cout<<"yes"<<endl;
            else cout<<"no"<<endl;
        }
    }
}
void solve()
{
    
    
    
}
int main()
{
    init();
    //solve();
    
    return 0;
}
HASH 表

 

void pre()
{
    int j=0;nxt[1]=0;//
    for(int i=1;i<len;i++)
    {
        while(j>0&&s[i+1]!=s[j+1]) j=nxt[j];
        
        if(s[i+1]==s[j+1]) j++;
        
        nxt[i+1]=j;
    }
}
void kmp()
{
    int j=0;
    for(int i=0;i<n;i++)
    {
        if(j>0&&B[j+1]!A[i+1]) j=p[j];
        if(A[i+1]==B[j+1]) j++;
        if(j==m){
            cout<<i+1-m+1<<endl;
            j=p[j];
        }
    }

}

//----------------------------
#include<cstdio>
#include<iostream>
#include<string>
#include<algorithm>
//#include<bits/stdc++.h>
using namespace std;

#define ll long long

const int maxn=1e6+5,b1=31,b2=47,mod1=1e6+3,mod2=1e6+9;//

char s[maxn];
int nxt[maxn],tot,len;

void pre()
{
    int j=0;nxt[1]=0;//
    for(int i=1;i<len;i++)
    {
        while(j>0&&s[i+1]!=s[j+1]) j=nxt[j];
        
        if(s[i+1]==s[j+1]) j++;
        
        nxt[i+1]=j;
    }
}
void solve()
{
    while(cin>>(s+1))
    {
        len=strlen(s+1);
        if(len==1&&s[1]=='.') break;
        
        pre();
        
        if(len%(len-nxt[len])==0)  cout<<len/(len-nxt[len])<<endl;//
        else cout<<"1"<<endl;
    }
    
}
int main()
{
    //init();
    solve();
    return 0;
}
KMP 最小循环 字串
#include<cstdio>
#include<bits/stdc++.h>
using namespace std;

char a[1005],b[1005];
int n,m;
int nxt[1005];

void pre()
{
    nxt[1]=0;
    int j=0;
    
    for(int i=1;i<=m;i++)
    {
        while(j>0&&b[j+1]!=b[i+1]) j=nxt[j];
        
        if(b[j+1]==b[i+1]) j++;
        
        nxt[i+1]=j;
    }
}

int kmp()
{
    int j=0,ans=0;
    
    for(int i=0;i<n;i++)
    {
        while(j>0&&a[i+1]!=b[j+1]) j=nxt[j];
        
        if(a[i+1]==b[j+1]) j++;
        
        if(j==m)
        {
            ans++;
            j=0;
        }
        /*
        if(j==m)
        {
            cout<<i+1 -m+1<<endl;
            j=p[j];
        }
        */
    }
    return ans;
}
int main()
{
    while(cin>>a+1)
    {
        cin>>b+1;
        n=strlen(a+1);
        m=strlen(b+1);
        if(a[1]=='#'&&n==1) break;
        pre();
        cout<<kmp()<<endl;
    }
    
    
    return 0;
}
KMP 最多不重叠字串/重叠字串位置

 

int ch[maxn][30],tot=1,bo[maxn];

void insert(char *s)
{
    int u=1,len=strlen(s);
    for(int i=0;i<len;i++)
    {
        int c=s[i]-'a';
        if(ch[u][c]==0) ch[u][c]=++tot;
        u=ch[u][c];
    }
    bo[u]=true;
}
int find(char *s)
{
    int u=1,len=strlen(s);
    for(int i=0;i<len;i++)
    {
        int c=s[i]-'a';
        if(ch[u][c]==0) return false;
        u=ch[u][c];
    }
    return true;
} 

//--------------------------

#include<cstdio>
#include<bits/stdc++.h>
using namespace std;

const int N=4e5+10,M=32;

int ch[N<<5][2],n,a[N],tot=1,l[N],r[N];

void clear()
{
    memset(ch,0,sizeof(ch));
}

void insert(int x)
{
    int u=1;
    //tot=0;
    for(int i=1<<30;i;i>>=1)
    {
        int c=(x&i)? 1:0;
        
        if(ch[u][c]==0) ch[u][c]=++tot; 
        
        u=ch[u][c];
    }
}
int find(int x)
{
    int u=1,res=0;
    
    for(int i=1<<30;i;i>>=1)
    {
        int c=(x&i)? 0:1;
        if(ch[u][c]) res+=i,u=ch[u][c];//
        else u=ch[u][!c];
    }
    return res;
}

int main()
{
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    
    int now;
    
    cin>>n;
    insert(now=0);
    
    for(int i=1;i<=n;i++)  
    {
        cin>>a[i];
        now^=a[i];
        insert(now);
        l[i]=max(l[i-1],find(now));
    }
        
    clear();
    tot=1;
    
    insert(now=0);// ^0对^不影响 + 初始化
    
    for(int i=n;i>=1;i--)  
    {
        now^=a[i];
        insert(now);
        r[i]=max(r[i+1],find(now));
    }  
   
    int ans=0;
    for(int i=1;i<n;i++) ans=max(ans,l[i]+r[i+1]);//
    
    cout<<ans<<endl;
    return 0;
}
Trie 二进制树

 

int ch[maxn][30],tot=1,bo[maxn],nxt[maxn];

void make(char *s)
{
    int len=strlen(s),u=1;
    for(int i=0;i<len;i++)
    {
        int c=s[i]-'a';
        if(ch[u][c]==0) ch[u][c]=++tot;
        u=ch[u][c];
    }
    bo[u]++;
}
void bfs()
{
    int que[maxn];    que[1]=1;nxt[1]=0;
    for(int i=0;i<26;i++) ch[0][i]=1;
    
    for(int q1=1,q2=1;q1<=q2;q1++) 
    {
        int u=que[q1++];
        if(ch[u][i]==0) ch[u][i]=ch[nxt[u]][i];
        else{
            que[++q2]=ch[u][i];
            int v=nxt[u];
            while(v>0&&ch[v][i]==0) v=nxt[v];
            nxt[ch[u][i]]=ch[v][i];
        }
    }
}
/*
int find(char*s)
{
    int u=1,len=strlen(s);
    for(int i=0;i<len;i++)
    {
        int c=s[i]-'a';
        int u=ch[u][c];
        if(bo[u]==1) return i;
    }
    return 0;
}*/
void find(char *s)
{
    int u=1,len=strlen(s),ans=0;
    for(int i=0;i<len;i++)
    {
        int c=s[i]-'a';
        int k=ch[u][c];
        while(k>=1)
        {
            ans+=bo[k];
            bo[k]=0;
            k=nxt[k];
        }
        u=ch[u][c];
    }
    return;
}

//-----------------------------

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;

const int N = 5e5 + 5;

int n, m, ch[N][30], nxt[N], tot = 1, bo[N];

void pre() {
    for (int i = 0; i < 50005; i++)
        for (int j = 0; j < 30; j++)
            ch[i][j] = 0;

    memset(bo, 0, sizeof(0));
    memset(nxt, 0, sizeof(nxt));
    //tot=1;

}
void make(char *s) {
    int len = strlen(s), u = 1;

    for (int i = 0; i < len; i++) {
        int c = s[i] - 'a';

        if (ch[u][c] == 0)
            ch[u][c] = ++tot; //memset(ch[tot],0,sizeof(ch[tot]));

        u = ch[u][c];
    }

    bo[u]++;

    return ;
}

void bfs() {
    for (int i = 0; i <= 25; i++)
        ch[0][i] = 1;

    int que[N];
    que[1] = 1;
    nxt[1] = 0;

    for (int q1 = 1, q2 = 1; q1 <= q2; q1++) {
        int u = que[q1];

        for (int i = 0; i <= 25; i++) {
            if (ch[u][i] == 0)
                ch[u][i] = ch[nxt[u]][i];
            else {
                //
                que[++q2] = ch[u][i];
                int v = nxt[u];

                while (v > 0  && ch[v][i] == 0)
                    v = nxt[v]; ////

                nxt[ch[u][i]] = ch[v][i];
            }
        }
    }

    /*
    queue<int> Q;    Q.push(1);
    nxt[1] = 0;

    while (!Q.empty()) {
        int u = Q.front();
        Q.pop();

        for (int i = 0; i < 26; ++i) {
            if (!ch[u][i])
                ch[u][i] = ch[nxt[u]][i];
            else {
                Q.push(ch[u][i]);
                int v = nxt[u];
                while(v && ch[v][i]==0) v=nxt[v];
                nxt[ch[u][i]] = ch[v][i];
            }
        }
    }
    */

}

int find(char *s) {
    int len = strlen(s), u = 1, ans = 0;

    for (int i = 0; i < len; i++) {
        int c = s[i] - 'a', k = ch[u][c];

        while (k >= 1) {
            ans += bo[k];
            bo[k] = 0;
            k = nxt[k];
        }

        u = ch[u][c]; //
    }

    return ans;
}
int main() {
    int T;
    cin >> T;

    while (T--) {
        pre();

        char s[N << 1];
        cin >> n;

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

            cin >> s;
            make(s);
        }

        bfs();
        cin >> s;
        cout << find(s) << endl;
    }

    return 0;
}
AC自动机 多模式串匹配母串

 

int ksm(int a,int b,int p)
{
    int res=1;
    while(b)
    {
        if(b%2==1) res=res*a%p;//一定会执行
        a=a*a%p;
        b/=2;
    }
    return res;
}

ksm
ksm

 

 

 

int pri[200],min_pri[200],cnt=0,n;
void get(int n)
{
    memset(min_pri,0,sizeof(min_pri));
    memset(pri,0,sizeof(pri));
    for(int i=2;i<=n;i++)
    {
        if(min_pri[i]==0) pri[++cnt]=i,min_pri[i]=i;
        for(int j=1;j<=cnt;j++)
        {
            if(pri[j]*i>n||pri[j]>min_pri[i]) break;
            min_pri[i*pri[j]]=pri[j];
        }
    }
    for(int i=1;i<=cnt;i++) cout<<pri[i]<<endl;
}
prime

 

find(x){ return fa[x]==x? x:fa[x]=find(fa[x])}

lian(int x,int y){
    int f1=find(x),f2=find(y);
    if(f1!=f2)
    {
        fa[f1]=f2;
        siz[f2]+=siz[f1]
    }
}
        
并查集 find+lian

 

 

 

 

/*

void tarjan(int x) {
    dfn[x] = low[x] = ++dfstime;
    stk[++top] = x;

    int cnt = 0; //!

    for (int i = head[x]; i; i = nxt[i]) {
        int y = to[i];

        if (dfn[y] == 0) {
            cnt++;
            tarjan(y);
            low[x] = min(low[x], low[y]);

            if ((x == root && cnt > 1) || (x != root && dfn[x] <= low[y]))
                cut[x] = 1;

            if (dfn[x] <= low[y]) {
                col++;
                bcc[col].clear();
                bcc[col].push_back(x);

                while (stk[top] != x) {
                    bcc[col].push_back(stk[top--]);
                }

                //top--;//割点属于多个双连通块
            }
        } else
            low[x] = min(low[x], dfn[y]);
    }
}
*/













#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <bits/stdc++.h>
using namespace std;

#define ll long long

const ll inf = 1e9, M = 1e5 + 5;

int n, m;
int head[M], to[M << 1], nxt[M << 1], tot;
int dfn[M], low[M], stk[M], top;
int cut[M], dfstime = 0, root, col;

vector<int> bcc[M];

void add(int x, int y) {
    to[++tot] = y;
    nxt[tot] = head[x];
    head[x] = tot;
}


void tarjan(int x) {
    dfn[x] = low[x] = ++dfstime;
    stk[++top] = x;

    int cnt = 0; //!

    for (int i = head[x]; i; i = nxt[i]) {
        int y = to[i];

        if (dfn[y] == 0) {
            cnt++;
            tarjan(y);
            low[x] = min(low[x], low[y]);

            if ((x == root && cnt > 1) || (x != root && dfn[x] <= low[y]))
                cut[x] = 1;

            if (dfn[x] <= low[y]) {
                col++;
                bcc[col].clear();
                bcc[col].push_back(x);

                while (stk[top] != x) {
                    bcc[col].push_back(stk[top--]);
                }

                //top--;//割点属于多个双连通块
            }
        } else
            low[x] = min(low[x], dfn[y]);
    }
}

void solve() {
    memset(head, 0, sizeof(head));
    memset(dfn, 0, sizeof(dfn));
    memset(low, 0, sizeof(low));
    memset(cut, 0, sizeof(cut));

    tot = top = dfstime = 0;
    n = 0;

    for (int i = 1; i <= m; i++) {
        int a, b;
        cin >> a >> b;
        n = max(n, max(a, b));
        add(a, b);
        add(b, a);

    }

    col = 0;

    for (int i = 1; i <= n; i++) {
        if (dfn[i] == 0) {
            root = i;
            tarjan(i);
        }
    }

    ll res = 0, num = 1;

    for (int i = 1; i <= col; i++) {
        int len = bcc[i].size();
        int gnum = 0;

        for (int j = 0; j < len; j++) {
            if (cut[bcc[i][j]])
                gnum++;
        }

        if (gnum == 0)
            res += 2, num = num * (len - 1) * len / 2;
        else if (gnum == 1)
            res++, num = num * (len - 1);
    }

    cout << res << " " << num << endl;
}
int main() {
    int t = 1;

    while (cin >> m && m) {
        cout << "Case " << t++ << ": ";
        solve();
    }

    return 0;
}
模板+bcc计数
/*
void tarjan(int u, int from)
{
    dfn[u] = low[u] = ++ timestamp;
    stk[ ++ top] = u;
    
    for (int i = h[u]; ~i; i = ne[i])
    {
        int j = e[i];
        if (!dfn[j])
        {
            tarjan(j, i);
            low[u] = min(low[u], low[j]);
            if (low[j] > dfn[u])
                is_bridge[i] = is_bridge[i ^ 1] = true;
        }
        else if (i != (1 ^ from))
            low[u] = min(low[u], dfn[j]);
    }
    
    if (dfn[u] == low[u])
    {
        dcc_cnt ++ ;
        int y;
        do
        {
            y = stk[top -- ];
            id[y] = dcc_cnt;
        } while (y != u);
    }
    
    return;
}
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct str{
   int n,t;
}e[2000000];
int n,m,tt,x,y,ans,t,h[200006],dfn[100006],low[100006];
void add(int x,int y){
    tt++;
    e[tt].t=y;
    e[tt].n=h[x];
    h[x]=tt;
}
void Tarjan(int x,int f){
    dfn[x]=low[x]=++t;
    
    for(int i=h[x];i;i=e[i].n){
        int v=e[i].t;
        if(v==f) continue;

        if(!dfn[v]){
            Tarjan(v,x);
            low[x]=min(low[x],low[v]);
            if(dfn[x]<low[v]) ans++;
        }
        else low[x]=min(low[x],dfn[v]);
    }
}
int main(){
      while (~scanf("%d%d",&n,&m)){
        if(n==0&&m==0) break;
        tt=t=ans=0;
        memset(h,0,sizeof(h));
        memset(dfn,0,sizeof(dfn));
        for(int i=1;i<=m;i++){
            scanf("%d%d",&x,&y);
            add(x,y),add(y,x);
        }
        Tarjan(1,1);
        printf("%d\n",ans);
    }
}
桥 计数

 

int dfs[N],low[N],num,st[N],top=0,co[N],col=0;
void tarjan(int u)
{
    dfs[u]=low[u]=++num;
    st[++top]=u;
    for(int i=head[u];i;i=nxt[i])
    {
        int v=to[i];
        if(dfn[v]==0)
        {
            tarjan(v);
            low[u]=min(low[v],low[u]);
        }
        else if(co[v]==0) low[u]=min(low[u],dfn[v])
    }
    if(low[u]==dfn[u])
    {
        co[u]=++col;
        while(st[top]!=u)
        {
            co[ st[top] ]=col;
            top--;
        }
        top--;
    }
}
tarjan

 

 

 

void dfs(int u,int fa)
{
    dep[u]=dep[fa]+1; f[u][0]=fa;
    for(int i=1;i<=20;i++) f[u][i]=f[f[u][i-1]][i-1];
    for(int i=head[u];i;i=nxt[i])
    {
        int v=to[i];
        if(v==fa) continue;
        dfs(v,u);
    }
}
int LCA (int x,int y)
{
    if(dep[x]<dep[y]) swap(x,y);
    for(int i=20;i>=0;i--)//二进制诬陷分割 
    {
        if(dep[f[x][i]]>=dep[y]) x=f[x][i];
        if(x==y) return;
    }
    for(int i=20;i>=0;i--)
    {
        if(f[x][i]!=f[y][i])
        {
            x=f[x][i];
            y=f[y][i];
        }       
    }
    return f[x][0];
}
int dis(int x,iny y){
    return dep[x]+dep[y]-2*dep[LCA(x,y)];
}LCA
LCA
a[1-n],lg[i],f[i][i] g[i][i]

lg[0]=-1; for(int i=1;i<=100;i++) lg[i]=lg[i>>1]+1;
for(int i=1;i<=n;i++) f[i][0]=a[i];

for(int j=1;j<=100;j++)
    for(int i=1;i+(1<<j)-1<=n;i++)
    {
        f[i][j]=max(f[i][j-1],f[i+1<<(j-1)][j-1] ); 
        g[i][j]=min(g[i][j-1],g[i+1<<(j-1)][j-1] ); 
    }
int k=lg[y-x+1];
return max(f[x][k],f[y-(1<<k)+1][
RMQ
void add(int u)
{
    f[u][0]=a[u];
    for(int i=1;u-(1<<i)+1>=1;i++) f[u][i]=max( f[u][i-1], f[ u-(1<<(i-1)) ][i-1] );
}
ll get(int x,int y)
{
    int t=lg[y-x+1];
    return max(f[y][t],f[x+(1<<t)-1][t]);
}

cin>>tmp;
a[++n]=tmp;
add(n);
动态开点+查询区间最值

 

a[1-n],add[n<<2],sum[n<<2]
void build(int k,int l,int r)
{
    if(l==r)
    {
        sum[k]=a[l];
        return;
    }
    int mid=l+r>>1;
    build(k<<1,l,mid);
    build(k<<1+1,mid+1,r);
    sum[k]=sum[k<<1]+sum[k<<1+1];
}
void Add(int k,int l,int r,int v)//manly process on K node
{
    add[k]+=v;
    sum[k]+=(r-l+1)*v;
}
void pushdown(int k,int l,int r)
{
    if(add[k]==0) return;
    int mid=l+r>>1;
    Add(k<<1,l,mid,add[k]);
    Add(k<<1+1,mid+1,r,add[k]);
    //sum[k]=sum[k<<1]+sum[k<<1+1];
    add[k]=0;
}
int query(int k,int l,int r,int x,int y)
{
    if(l>y||r<x) return 0;
    if(x<=l&&r<=y) return sum[k];
    pushdown(k,l,r);
    int mid=l+r>>1,res=0;
    if(x<=mid) res+=query(k<<1,l,mid,x,y);
    if(y>mid) res+=query(k<<1|1,mid+1,r,x,y);
    return res;
}
void areaAdd(int k,int l,int r,int x,int y,int val)
{
    if(l>y||r<x) return;
    if(x<=l&&r<=y)
    {
        add[k]+=val;
        sum[k]+=(r-l+1)*val;
        return;
    }
    pushdown(k,l,r);
    int mid=l+r>>1;
    if(x<=mid) modify(k<<1,l,mid,x,y,val);//!
    if(y>mid) modify(k<<1|1,mid+1,r,x,y,val);
    sum[k]=sum[k<<1]+sum[k<<1|1];
}

build(1,1,n);
query(1,1,n,A,B);
modify(1,1,n,A,B,val);

线段树
常规线段树
a[1-n],add[n<<2],minn[n<<2]

void build(int k,int l,int r)
{
    if(l==r)
    {
        sum[k]=a[l];
        minn[k]=a[l];
        return;
    }
    int mid=l+r>>1;
    build(k<<1,l,mid);
    build(k<<1+1,mid+1,r);
    minn[k]=min(minn[k<<1],minn[k<<1|1]);
}

void change(int k,int l,int r,int x,int val)//ÒòΪchange±ØÐëҪ׼ȷ 
{
    if(l>x||r<x) return;
    if(l==r&&l==x)
    {
        minn[k]=val;
        return;
    }
    int mid=l+r>>1;
    change(k<<1,l,mid,x,val);
    change(k<<1|1,mid+1,r,x,val);
    minn[k]=min(minn[k<<1],minn[k<<1|1]);
}
int query(int k,int l,int r,int x,int y)
{
    if(l>y||r<x) return;
    if(x<=l&&r<=y) return minn[k];
    int mid=l+r>>1;
    return min(query(k<<1,l,mid,x,y),query(k<<1|1,mid+1,r,x,y));
}

build(1,1,n);
query(1,1,n,A,B);
change(1,1,n,A,val);



struct +segmenttree

struct tree{
    int l,r;
    ll minn;
}st[maxn<<2];

void build(int k,int l,int r)//
{
    st[k].l=l,st[k].r=r,st[k].minn=inf;
    if(st[k].l==st[k].r) return;
    int mid=st[k].l+st[k].r>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    st[k].minn=min(st[k<<1].minn,st[k<<1|1].minn);
}

void change(int k,int pos,int val)
{
    if(st[k].l>pos||st[k].r<pos) return;
    if(st[k].l==st[k].r&&st[k].l==pos)
    {
        st[k].minn=val;
        return;
    }
    int mid=st[k].l+st[k].r>>1;
    change(k<<1,pos,val);
    change(k<<1|1,pos,val);
    st[k].minn=min(st[k<<1].minn,st[k<<1|1].minn);
} 
ll query(int k,int x,int y)
{
    if(st[k].l>y||st[k].r<x) return inf;
    if(x<=st[k].l&&st[k].r<=y) return st[k].minn;
    int mid=st[k].l+st[k].r>>1; ll res=inf;
    if(x<=mid) res=min(res,query(k<<1,x,y));
    if(mid<=y) res=min(res,query(k<<1|1,x,y));
    return res;
}
线段树+minn+change
/*
5 5 38
1 5 4 2 3
2 1 4 1
3 2 5
1 2 4 2
2 3 5 5
3 1 4

17
2
*/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------debug\n");
using namespace std;
const int maxn=100010;

int n,q,mod,a[maxn];
struct node{
    int l,r;
    ll add,mul,sum;
}s[maxn<<2]; //long long 只用在 大数据上 否则 溢出 /溢出 

void build(int k,int l,int r)
{
    s[k].l=l,s[k].r=r,s[k].mul=1  ;
    if(l==r)
    {
        s[k].sum=a[l]%mod;
        return;
    }
    int mid=l+r>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    s[k].sum=(s[k<<1].sum+s[k<<1|1].sum)%mod;
}
void pushdown(int k)
{
    if(s[k].add==0&&s[k].mul==1) return;
    
    s[k<<1].sum=( s[k<<1].sum*s[k].mul + (s[k<<1].r-s[k<<1].l+1)*s[k].add )%mod;
    s[k<<1|1].sum=( s[k<<1|1].sum*s[k].mul+ (s[k<<1|1].r-s[k<<1|1].l+1)*s[k].add )%mod;
    
    s[k<<1].mul=s[k<<1].mul*s[k].mul %mod;
    s[k<<1|1].mul=s[k<<1|1].mul*s[k].mul %mod;
    
    s[k<<1].add=(s[k<<1].add*s[k].mul+s[k].add)%mod;
    s[k<<1|1].add=(s[k<<1|1].add*s[k].mul+s[k].add)%mod;
    
    s[k].add=0;
    s[k].mul=1;
}

void areaAdd(int k,int x,int y,int val)
{
    if(s[k].l>y||s[k].r<x) return;
    if(s[k].l>=x&&s[k].r<=y)
    {
        s[k].add=(s[k].add+val)%mod;
        s[k].sum=(s[k].sum+(s[k].r-s[k].l+1)*val )%mod;
        return;
    }
    pushdown(k);
    int mid=s[k].l+s[k].r>>1;
    if(x<=mid) areaAdd(k<<1,x,y,val);
    if(mid<y) areaAdd(k<<1|1,x,y,val);
    s[k].sum=(s[k<<1].sum+s[k<<1|1].sum)%mod;
}
void areaMul(int k,int x,int y,int val)
{
    if(s[k].l>y||s[k].r<x) return;
    if(s[k].l>=x&&s[k].r<=y)
    {
        s[k].add=(s[k].add*val)%mod;
        s[k].sum=(s[k].sum*val )%mod;
        s[k].mul=(s[k].mul*val) %mod;
        return;
    }
    pushdown(k);
    int mid=s[k].l+s[k].r>>1;
    if(x<=mid) areaMul(k<<1,x,y,val);
    if(mid<y) areaMul(k<<1|1,x,y,val);
    s[k].sum=(s[k<<1].sum+s[k<<1|1].sum)%mod;
}

ll query(int k,int x,int y)
{
    if(s[k].l>y||s[k].r<x) return 0;
    if(s[k].l>=x&&s[k].r<=y) return s[k].sum;
    pushdown(k);
    int mid=s[k].l+s[k].r>>1;    ll res=0;
    if(x<=mid) res=(res+query(k<<1,x,y)) %mod;
    if(mid<y) res=(res+query(k<<1|1,x,y)) %mod; // ER mid<=x -> or mid>=x miss
    return res;
}

int main()
{
    ios::sync_with_stdio(false); cin.tie(0);
    cin>>n>>q>>mod;
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,1,n);
    for(int i=1;i<=q;i++)
    {
        int op; cin>>op;
        if(op==1){
            int x,y,k; cin>>x>>y>>k;
            areaMul(1,x,y,k);
        }
        else if(op==2){
            int x,y,k; cin>>x>>y>>k;
            areaAdd(1,x,y,k);
        }
        else if(op==3){
            int x,y; cin>>x>>y;
            //ddd
            cout<<query(1,x,y)%mod<<'\n';
        }
    }
    
    return 0;
}
线段树 + *
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<bits/stdc++.h>
#define ll long long
//#define int long long
#define ddd printf("-----------------debug\n");
using namespace std;
const int maxn=1e6+10;
const ll inf=1e18+10;
 
ll n,q,a[maxn];
struct node{
    ll l,r;
    ll add,maxx,cv;
}s[maxn<<2];

void build(int k,int l,int r)
{
    s[k].l=l,s[k].r=r,s[k].cv=-inf,s[k].maxx=-inf;
    if(l==r)
    {
        s[k].maxx=a[l];
        return;
    }
    int mid=l+r>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    s[k].maxx=max(s[k<<1].maxx,s[k<<1|1].maxx);
}

void pushdown(int k)
{
    if(s[k].cv!=-inf)
    {
        s[k<<1].maxx=s[k<<1|1].maxx=s[k].cv;
        s[k<<1].cv=s[k<<1|1].cv=s[k].cv;
        s[k<<1].add=s[k<<1|1].add=0;
        s[k].cv=-inf;
    }
    if(s[k].add)
    {
        s[k<<1].maxx+=s[k].add; s[k<<1|1].maxx+=s[k].add;
        //s[k<<1].cv+=s[k].add; s[k<<1|1].cv+=s[k].add;
        s[k<<1].add+=s[k].add; s[k<<1|1].add+=s[k].add;
        s[k].add=0;
    }
}

void change(int k,int x,int y,int val)
{
    if(s[k].l>y||s[k].r<x) return;
    if(s[k].l>=x&&s[k].r<=y)
    {
        s[k].cv=val;//cv-> 全部改成 
        s[k].maxx=val;
        s[k].add=0;
        return;
    }
    pushdown(k);
    int mid=s[k].l+s[k].r>>1;
    if(mid>=x) change(k<<1,x,y,val);
    if(mid<=y) change(k<<1|1,x,y,val);
    s[k].maxx=max(s[k<<1].maxx,s[k<<1|1].maxx);
}
void areaAdd(int k,int x,int y,int val)
{
    if(s[k].l>y||s[k].r<x) return;
    if(s[k].l>=x&&s[k].r<=y)
    {
    //    s[k].cv+=val;
        s[k].maxx+=val;
        s[k].add+=val;
        return;
    }
    pushdown(k);
    int mid=s[k].l+s[k].r>>1;
    if(mid>=x) areaAdd(k<<1,x,y,val);
    if(mid<=y) areaAdd(k<<1|1,x,y,val);
    s[k].maxx=max(s[k<<1].maxx,s[k<<1|1].maxx);
}
ll query(int k,int x,int y)
{
    if(s[k].l>y||s[k].r<x) return -inf;
    if(s[k].l>=x&&s[k].r<=y) return s[k].maxx;
    pushdown(k);
    int mid=s[k].l+s[k].r>>1; ll res=-inf;
    if(mid>=x) res=max(res,query(k<<1,x,y)) ; 
    if(mid<=y) res=max(res,query(k<<1|1,x,y)) ;
    return res;
}
int main()
{
    ios::sync_with_stdio(false); cin.tie(0);
    cin>>n>>q;
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,1,n);
    
    for(int i=1;i<=q;i++)
    {
        int op; cin>>op;
        if(op==1){
            int l,r,x; cin>>l>>r>>x;
            change(1,l,r,x);
        }
        else if(op==2){
            int l,r,x; cin>>l>>r>>x;
            areaAdd(1,l,r,x);
        }
        else{
            int l,r; cin>>l>>r;
            cout<<query(1,l,r)<<'\n';
        }
    }
    
    return 0;
}
线段树+覆盖+区间加减

 


 逆序对个数-》交换次数 

postion-val max-》冒泡排序 轮数

int tmp[maxn],ans;
void merge_sort(int l,int mid,int r)
{
    int ll=l,rr=mid+1,tmpx=l;
    while(ll<=mid&&rr<=r)
    {
        if(a[ll]<=a[rr]) tmp[tmpx++]=a[ll++];
        else tmp[tmpx++]=a[rr++],ans+=mid-ll+1;
    }
    while(ll<=mid) tmp[tmpx++]=a[ll++];
    while(rr<=r) tmp[tmpx++]=a[rr++];
    for(int i=l;i<=r;i++) a[i]=tmp[i];
}
void merge(int l,int r)
{
    if(l<r)
    {
        int mid=l+r>>1;
        merge(l,mid); merge(mid+1,r);
        merge_sort(l,mid,r);
    }
}

cout<<ans<<endl; 
merge_sort

d[maxn],vis[maxn],w[maxn][maxn];
void prim(int rt)
{
    memset(vis,0,sizeof(vis));
    memset(d,0x3f3f3f3f,sizeof((d)));
    d[rt]=0;//不需要vis 
    
    ll ans;
    for(int i=1;i<=n;i++)
    {
        int minn=0x3f3f3f3f,k;
        for(int j=1;j<=n;j++){
            if(vis[j]==0&&d[j]<minn) minn=d[j],k=j;
        }
        vis[k]=1; ans+=d[k];
        
        for(int j=1;j<=n;j++){
            if(vis[j]==0&&w[j][k]<d[j]) d[j]=w[j][k];
        }
    }
}
Prim 最小生成树
fa[maxn],ans;
struct edge{
    int x,y,w;
}e[maxn];
int find(int x){return fa[x]==x? x:fa[x]=find(x);}
bool cmp(edge a,edge b){return a.w<b.w;}

sort(e+1,e+1+m);
void kruskal()
{
    for(int i=1;i<=n;i++) fa[i]=i;//!!!!!!!!
    int k;
    for(int i=1;i<=m;i++)
    {
        int f1=find(e[i].x),f2=find(e[i].y);
        if(f1!=f2){
            fa[f1]=f2;
            ans+=e[i].w;
            k++; if(k==n-1) break;
        }
    }
    if(k<n-1) cout<<"impossible"<<'\n';
}
kruskal

 

floyd(n^3) 有/无向 图都可以

cin>>map[i][j]
memset(d[i],inf,sizeof(d[i]));
for(int i=1;i<=n;i++)
    for(int i=1;i<=n;i++)
        d[i][j]=mpa[i][j];

for(int k=1;k<=n;k++)//枚举中间点
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(d[i][k]!=inf&&d[k][j]!=inf&&d[i][j]>d[i][k]+d[k][j])
                    d[i][j]=d[i][k]+d[k][j];
floyd,边+/-,但不能有负环
// 图论 d[][] 容易exceed
// j=i+1~k   否则ans->0 
/*
5 7
1 4 1
1 3 300
3 1 10
1 2 16
2 3 100
2 5 15
5 3 20

1 3 5 2
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<bits/stdc++.h>
#define ll long long
#define ddd printf("----------------------\n");
using namespace std;
const int maxn=3e2+10 ;

ll ans=0x3f3f3f3f;
int a[maxn][maxn],d[maxn][maxn],pos[maxn][maxn];
int n,m;
vector<int> path;

void get_path(int x,int y)
{
    if(pos[x][y]==0) return;
    get_path(x,pos[x][y]);
    path.push_back(pos[x][y]);
    get_path(pos[x][y],y);
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;
    
    memset(a,0x3f3f3f3f,sizeof(a));
    for(int i=1;i<=n;i++) a[i][i]=0;
    
    for(int i=1;i<=m;i++){
        int u,v,val;cin>>u>>v>>val;
        a[u][v]=a[v][u]=min(val,a[v][u]);
    }
    memcpy(d,a,sizeof(a));
    
    for(int k=1;k<=n;k++)
    {
        for(int i=1;i<k;i++)
        {
            for(int j=i+1;j<k;j++){//
                if( ((ll)d[i][j]+a[i][k]+a[k][j])<ans){
                    ans=d[i][j]+a[i][k]+a[k][j];
                    path.clear();
                    path.push_back(i);
                    get_path(i,j);
                    path.push_back(j);
                    path.push_back(k);
                }    
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(d[i][j]>d[i][k]+d[k][j]){
                    d[i][j]=d[i][k]+d[k][j];
                    pos[i][j]=pos[j][i]=k;
                }
            }
        }
    }
    if(ans==0x3f3f3f3f) {cout<<"No solution."<<'\n'; return 0; }
    for(int i=0;i<path.size();i++) cout<<path[i]<<" ";
    cout<<'\n';
    
    return 0;
}
floyd->最小环

 

 

 

int dis[maxn],vis[maxn];

struct edge{
    int to,nxt,w;
}e[maxn];
void  add(int u,int v,int w){
    e[++cnt].to=v;
    e[cnt].nxt=head[u];
    e[cnt].w=w;
    head[u]=cnt;
}
void dij()
{
    memset(dis,0x3f3f3f3f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    
    priority_queue< pair<int,int> > q;
    dis[1]=0;
    q.push(make_pair(0,1));
    while(!q.empty())
    {
        int u=q.top().second ; q.pop();
        if(vis[u]) continue; vis[u]=1;
        for(int i=head[u];i;i=e[i].nxt)
        {
            int v=e[i].to;
            if(dis[v]>dis[u]+e[i].w)
                dis[v]>dis[u]+e[i].w,  q.push(make_pair(-dis[v],v)); 
        }
    }
    
    cout<<dis[n];    
}
dij
int dis[maxn],vis[maxn];

struct edge{
    int to,nxt,w;
}e[maxn];
void  add(int u,int v,int w){
    e[++cnt].to=v;
    e[cnt].nxt=head[u];
    e[cnt].w=w;
    head[u]=cnt;
}
void spfa()
{
    queue<int> q;
    
    memset(dis,0x3f3f3f3f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    dis[1]=0,vis[1]=1; q.push(1);
    
    while(q.size())
    {
        int u.q.front(); q.pop(); 
        vis[u]=0;
        for(int i=head[u];i;i=e[i].nxt)
        {
            int v=e[i].to;
            if(dis[v]>dis[u]+e[i].w)
                dis[v]=dis[u]+e[i].w, if(vis[v]==0) q.push(v),vis[v]=1;//vis -> in the queue
        }
        
    }
    
    cout<<dis[n]<<'\n';
}
spfa
head[maxn],to[maxn],nxt[maxn],w[maxn];
dis[maxn],vis[maxn],len,sum;

void spfa_LLL_SLF()
{
    deque<int> q;
    memset(dis,0x3f3f3f3f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    
    dis[s]=0,vis[s]=1;
    q.push_back(s); len++; sum+=dis[s];
    
    while(!q.empty())
    {
        int u=q.front(); q.pop_front();
        if(dis[u]*len>sum)
        {
             q.push_back(u);//LLL
            continue;
        }
        vis[u]=0; len--; sum-=dis[u];
        
        for(int i=head[u];i;i=nxt[i])
        {
            int v=to[i];
            if(dis[v]>dis[u]+w[i]) dis[v]=dis[u]+w[i];
            if(vis[v]==0)
            {
                vis[v]=1;
                if(q.empty()||dis[v]<dis[q.front()]) q.push_front(v);
                else q.push_back(v);
                
                sum+=dis[v];
                len++;
            }
        }        
    }

}
spfa_lll_slf
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map>
//#include<queue>
//#include<vector>
//#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------------\n");
using namespace std;
const int maxn=1e1 ;

int head[maxn],to[maxn],nxt[maxn],w[maxn],tot;
int dis[maxn],vis[maxn],cnt[maxn];
int n,m;

void add(int u,int v,int val){
    to[++tot]=v,nxt[tot]=head[u],head[u]=tot,w[tot]=val;
}
int spfa_bfs(int rt)
{
    memset(vis,0,sizeof(vis));
    memset(dis,0x3f3f3f3f,sizeof(dis));
    queue<int> q; q.push(rt);
    dis[rt]=0,vis[rt]=1,cnt[rt]=1;
    while(q.size())
    {
        int u=q.front();q.pop(); vis[u]=0;
        for(int i=head[u];i;i=nxt[i])
        {
            int v=to[i];
            if(dis[v]>dis[u]+w[i])
            {
                dis[v]=dis[u]+w[i];
                cnt[v]=cnt[u]+1;
                if(cnt[v]>n) return 0;
                if(vis[v]==0) q.push(v),vis[v]=1;
            }
            
        } 
    }
    return 1;
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int u,v,val;cin>>u>>v>>val;
        add(u,v,val),add(v,u,val);
    }
    
    if(spfa_bfs(1)==0) cout<<"-cirlce"<<'\n';
    else cout<<dis[n]<<'\n';
    
    return 0;
}
/*
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 10005
#define M 20005
using namespace std;
int n,m,t,oo;
int v[M],w[M],next[M];
int d[N],cnt[N],first[N];
bool flag,vis[N];
void add(int x,int y,int z)
{
        t++;
        next[t]=first[x];
        first[x]=t;
        v[t]=y;
        w[t]=z;
}
bool SPFA(int s)
{
        int x,y,i,j;
        queue<int>q;
        memset(d,127,sizeof(d));
        memset(vis,false,sizeof(vis));
        while(!q.empty())  q.pop();
        d[s]=0;
        cnt[s]=1;
        q.push(s);
        vis[s]=true;
        while(!q.empty())
        {
                x=q.front();
                q.pop();
                vis[x]=false;
                for(i=first[x];i;i=next[i])
                {
                        y=v[i];
                        if(d[y]>d[x]+w[i])
                        {
                                d[y]=d[x]+w[i];
                                cnt[y]=cnt[x]+1;
                                if(cnt[y]>n)
                                  return false;
                                if(!vis[y])
                                {
                                        q.push(y);
                                        vis[y]=true;
                                }
                        }
                }
        }
        return true;
}
int main()
{
        int x,y,z,i;
        scanf("%d%d",&n,&m);
        for(i=1;i<=m;++i)
        {
            scanf("%d%d%d",&x,&y,&z);
                add(x,y,z);
                add(y,x,z);
        }
        flag=SPFA(1);
        if(!flag)  printf("Yes\n");
        else  printf("No\n");
        return 0;
}*/
spfa-bfs判断负环+最短路
有负环dfs更快,若无则bfs更快
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map>
//#include<queue>
//#include<vector>
//#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------------\n");
using namespace std;
const int maxn=1e1 ;

int head[maxn],to[maxn],nxt[maxn],w[maxn],tot;
int dis[maxn],vis[maxn];
int n,m,flag;

void add(int u,int v,int val){
    to[++tot]=v,nxt[tot]=head[u],head[u]=tot,w[tot]=val;
}

void dfs(int u)
{
    vis[u]=1;
    for(int i=head[u];i;i=nxt[i])
    {
        int v=to[i];
        if(dis[v]>dis[u]+w[i])
        {
            if(vis[v]){
                flag=1;
                return;
            }
            dis[v]=dis[u]+w[i];
            dfs(v);
        }
    }
    vis[u]=0;
}
void spfa_dfs(int rt)
{
    memset(vis,0,sizeof(vis));
    memset(dis,0x3f3f3f3f,sizeof(dis));

    dis[rt]=0,vis[rt]=1;    
    dfs(rt);
}

int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int u,v,val;cin>>u>>v>>val;
        add(u,v,val),add(v,u,val);
    }
    spfa_dfs(1);
    
    if(flag) cout<<"-circle"<<'\n';
    else cout<<dis[n];
    
    return 0;
}

/*#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 10005
#define M 20005
using namespace std;
int n,m,t;
int d[N],first[N];
int v[M],w[M],next[M];
bool flag,vis[N];
void add(int x,int y,int z)
{
    t++;
    next[t]=first[x];
    first[x]=t;
    v[t]=y;
    w[t]=z;
}
void spfa(int x)
{
    int i,j;
    vis[x]=true;
    for(i=first[x];i;i=next[i])
    {
        j=v[i];
        if(d[j]>d[x]+w[i])
        {
            if(vis[j])
            {
                flag=false;
                return;
            }
            d[j]=d[x]+w[i];
            spfa(j);
        }
    }
    vis[x]=false;
}
int main()
{
    int x,y,z,i;
    scanf("%d%d",&n,&m);
    for(i=1;i<=m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    memset(d,127,sizeof(d));
    d[1]=0;
    flag=true;
    spfa(1);
    if(!flag)  printf("Yes");
    else  printf("No");
    return 0;
}*/
spfa-dfs判断负环+最短路

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

root

 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted @ 2023-07-04 14:45  JMXZ  阅读(21)  评论(0)    收藏  举报