DAY 1

%%%神犇vanilla!!!AK虐全场!!!

%%%神犇vanilla!!!AK虐全场!!!

%%%神犇vanilla!!!AK虐全场!!!

%%%神犇vanilla:vanilla为了算pow(x,1/3),他竟然想出了可以先算sqrt(sqrt(x))=y,再算pow(y,4/3)的优秀算法!!!

一、讲课

1、强连通分量
(1)定义

有向图G中,若两个顶点u,v之间能够相互到达,则称u,v是强联通的
若有向图G的每两个顶点都强连通,则G是一个强连通图
有向图的极大强连通子图,称为强连通分量

(2)一些推导

1.强连通分量是针对有向图的
2.有向图G中的每个点都属于且只属于一个强连通分量
3.若A,B属于同一个强连通分量,B,C属于同一个强连通分量,则A,C也属于同一个强连通分量

(3)算法
Tarjan

主体过程:
从某个点开始,DFS整个图,每访问到一个新的节点就将其压入栈中
为每个点记录两个量dfn和low
其中dfn[x]是时间戳,代表x是第几个被访问到的点
low[x]代表x最多只经过一条非树边(虚线)能到达的点中,dfn的最小值
维护low值的方式:对于x的每个出点j
若j还没被搜到,则先搜索j ,然后用low[j]来更新low[x]
否则若j还在栈中,则直接用dfn[j]来更新low[x]
x的出边全部遍历之后,若dfn[x]==low[x],则从栈顶到x的这部分属于同一个强连通分量,把这段弹栈
模板

void tarjan(int x) {
    dfn[x]=low[x]=++idx;
    s[++top]=x;
    in[x]=1;
    for(int u=head[x]; u; u=edge[u].next) {
        int t=edge[u].to;
        if(!dfn[t]) {
            tarjan(t);
            low[x]=min(low[x],low[t]);
        }
        else if(in[t]){
            low[x]=min(low[x],dfn[t]);
        } 
    }
    if(dfn[x]==low[x]) {
        tot++;
        while(s[top]!=x){
            ans[tot].push_back(s[top]);
            in[s[top]]=0,top--;
        }
        ans[tot].push_back(s[top]);
        in[x]=0,top--;
    }
}
Kosaraju

复杂度高,用处很少,在此不再详述

(4)例题

[Usaco2006 Jan]The Cow Prom
直接上Tarjan就好了,顺便维护每个强连通分量的大小
[HAOI2006]受欢迎的牛
先缩点,然后看出度为0的强连通分量是否只有一个
如果有,则答案为这个强连通分量的大小
否则没有能被所有点到达的点

#include<bits/stdc++.h>
#define ll long long
#define idg isdigit
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define fed(i,j) for(int i=head[j];i;i=e[i].nxt)
#define rd1 inline int read(){int x=0,f=1;char ch=getchar();
#define rd2 for(;!idg(ch);ch=getchar())if(ch=='-')f=-1;
#define rd3 for(;idg(ch);ch=getchar())x=x*10+ch-'0';return x*f;}
#define fastread rd1 rd2 rd3
#define rd(x) x=read()
#define fin(x) freopen(x".in","r",stdin)
#define fout(x) freopen(x".out","w",stdout)
using namespace std;
fastread
int n,m,a,b,tot,head[10005],tot2,head2[10005];
struct edge{
    int t,nxt;
}e[50005],e2[50005];
void add(int u,int v){
    e[++tot]=(edge){v,head[u]};
    head[u]=tot;
}
bool in[10005];
int dfn[10005],low[10005],ans[10005];
int fr[10005],idx,s[10005],top,num,tmp;
void tarjan(int x){
    dfn[x]=low[x]=++idx;
    in[x]=1;s[++top]=x;
    fed(i,x){int v=e[i].t;
        if(!dfn[v]){
            tarjan(v);
            low[x]=min(low[x],low[v]);
        }
        else if(in[v])low[x]=min(low[x],dfn[v]);
    }
    if(dfn[x]==low[x]){
        num++;
        while(s[top]!=x){
            in[s[top]]=0;
            ans[num]++;
            fr[s[top]]=num;
            top--;
        }
        in[s[top]]=0;
        ans[num]++;
        fr[x]=num;
        top--;
    }
}
void added(int u,int v){
    e2[++tot2]=(edge){v,head2[u]};
    head2[u]=tot2;
}
int main(){
    n=read(),m=read();
    rep(i,1,m){
        a=read(),b=read();
        add(a,b);
    }
    rep(i,1,n)if(!dfn[i])tarjan(i);
    rep(i,1,n)fed(j,i)if(fr[e[j].t]!=fr[i])
        added(fr[i],fr[e[j].t]);
    rep(i,1,num)if(!head2[i]){
        if(tmp){
            tmp=0;
            break;
        }
        else tmp=ans[i];
    }
    printf("%d", tmp);
    return 0;
}

BZOJ2140: 稳定婚姻
设大写字母为男性,小写字母是女性
连边,B->b(男->女)的是夫妻关系,b->B(女->男)的是情人关系
所以我们按照这种方式来建图,若Aa在同一个强连通分量中,则这对婚姻是不稳定的

2、双连通分量
(1)定义

无向图G中,若去掉点x及其所有相邻的边之后,G的连通块个数增加了,则称x是G的一个割点
(割点求法:tarjan算法如果点x有一个出点的low值>=dfn[x],则x是一个割点)
无向图G中,若去掉边e之后,G的连通块个数增加了,则称e是G的一个桥
双连通分量
对于一个无向图G,若其不存在桥,则称其是一个边双连通图
一个无向图G的极大边双连通子图成为G的边双连通分量
对于一个无向图G,若其不存在割点,则称其是一个点双连通图
一个无向图G的极大点双连通子图成为G的点双连通分量
边双连通分量
A,B在同一个边双中当且仅当A,B之间有两条边不相交路径
因此,每个点属于且只属于一个边双连通分量
注意:边双连通分量缩点后会变成一棵树
边双求法:还是用Tarjan算法,几乎和求强连通分量的方式一样
(从DFS树的角度考虑,我们把树边当成从上到下的有向边,非树边当成从下到上的有向边,这个图中的强连通分量就是正常无向图中的边双连通分量)
点双连通分量
由于一个割点可能在多个点双连通分量里,所以需要在普通的tarjan算法基础上做一些改动,把边压入栈中而不是点,这样我们开始弹栈的时候最后剩下的这条边就会把割点留下了

(2)例题

[Usaco2006 Jan] Redundant Paths :
先把边双连通分量缩起来然后贪心地把所有度数为1的点一对一对的连起来
所以答案=⌈缩点之后度数为1的点的个数/2⌉

//复制的代码
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
int n;
struct map {
    int s,t,x;
    int next;
} a[150001];
int edge;
int head[10001];
int scc,cnt;
bool v[10001];
int s[10001],top;
int dfn[10001],low[10001],belong[10001];
int fa[10001];
int indeg[10001];
int tot=0;
inline void add(int s,int t) {
    a[edge].next=head[s];
    head[s]=edge;
    a[edge].s=s;
    a[edge].t=t;
    a[edge].x=tot;
}
inline int min(int x,int y) {
    if(x<y)
        return x;
    return y;
}
void tarjan(int d) {
    int i,x;
    cnt++;
    dfn[d]=cnt;
    low[d]=cnt;
    top++;
    s[top]=d;
    v[d]=true;
    for(i=head[d]; i!=0; i=a[i].next) {
        x=a[i].t;
        if(a[i].x==fa[d])
            continue;
        if(dfn[x]==0) {
            fa[x]=a[i].x;
            tarjan(x);
            low[d]=min(low[d],low[x]);
        } else if(v[x]&&low[d]>dfn[x])
            low[d]=dfn[x];
    }
    if(dfn[d]==low[d]) {
        scc++;
        x=s[top];
        top--;
        while(x!=d) {
            v[x]=false;
            belong[x]=scc;
            x=s[top];
            top--;
        }
        v[x]=false;
        belong[x]=scc;
    }
}
inline void count_edge() {
    int i;
    for(i=1; i<=edge; i=i+2) {
        if(belong[a[i].s]==belong[a[i].t])
            continue;
        indeg[belong[a[i].s]]++;
        indeg[belong[a[i].t]]++;
    }
}
int main() {
    int n,m;
    scanf("%d%d",&n,&m);
    int s,t;
    int i,j;
    for(i=1; i<=m; i++) {
        scanf("%d%d",&s,&t);
        edge++;
        tot++;
        add(s,t);
        edge++;
        add(t,s);
    }
    memset(v,false,sizeof(v));
    for(i=1; i<=n; i++)
        if(belong[i]==0)
            tarjan(i);
    count_edge();
    int leaf=0;
    for(i=1; i<=scc; i++)
        if(indeg[i]==1)
            leaf++;
    int ans=(leaf+1)/2;
    printf("%d\n",ans);
    return 0;
}
3、二分图匹配
(1)定义

设G=(V,E)为一个无向图,若V存在两个子集A,B,使得A∪B=V,A∩B=∅,且保证对于∀(i,j)∈E,有i∈A&&j∈B或i∈B&&j∈A,则称G是一个二分图(二部图)简而言之就是如果能把G划分成两部分,使得每一部分内都不自己和自己连边(详情咨询”wj和zsy的连边之战“),G就是一个二分图
二分图的判定:从每个连通块开始DFS,尝试染色,每次向外扩展时分两种情况讨论:
1.没染过色,那就染成相反的颜色然后从他开始DFS
2.染过色了,检验其是否合法,不合法退出,合法跳过
匹配:对于二分图G的一个子图M=(V,E)若E的任意两条边都不依附于V中的同一个顶点,则称M是一个匹配
最大匹配:若M是G的所有匹配当中边数最多的一个匹配,则称M是一个最大匹配(二分图的最大匹配可能有多个)
完美匹配:如果一个匹配中图中的每个顶点都和匹配中的某条边关联,则称这个匹配是一个完美匹配
Hall定理:有二分图G=(V,E),其中V划分为A,B,C是A的子集,且|C|=k,存在一个匹配M使得C中的每一个点都存在于匹配中,当且仅当对于∀1<=i<=k,C中任意i个点都至少和B中i个点相连 (证明略)

(2)算法

匈牙利(求最大匹配)
主要思想是不断地寻找增广路来使得总匹配数+1
模板

bool match(int u){
    rep(i,1,n){
        if(v[i]||!m[u][i])continue;
        v[i]=1;
        if(!matching[i]||match(matching[i])){
            matching[i]=u;
            return 1;
        }
    }
    return 0;
}
void hungarian(){
    rep(i,1,l){
        memset(v,0,sizeof(v));
        if(match(i))ans++;
    }
    return;
}
重要知识点: 二分图最小点覆盖 = 二分图最大匹配 二分图最大点独立集 = 总点数 - 二分图最大匹配
(3)例题

[Usaco2005 nov]Asteroids : 我们把对行和列建一个二分图,若存在小行星(i,j),就在行i和列j之间连一条边,现在问题就转化为了求二分图最小点覆盖,直接跑匈牙利算法即可

#include<cstdio>
using namespace std;
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct map {
    int s,t;
    int next;
} a[1000001];
int head[100001];
int edge;
bool v[100001];
int lk[100001];
int n;
inline void add(int s,int t) {
    a[edge].next=head[s];
    head[s]=edge;
    a[edge].s=s;
    a[edge].t=t;
}
inline bool find(int d) {
    int i;
    for(i=head[d]; i!=0; i=a[i].next) {
        int t=a[i].t;
        if(!v[t]) {
            v[t]=true;
            if(lk[t]==0||find(lk[t])) {
                lk[t]=d;
                return true;
            }
        }
    }
    return false;
}
inline int work() {
    int i;
    int ans=0;
    for(i=1; i<=n; i++) {
        memset(v,false,sizeof(v));
        if(find(i))
            ans++;
    }
    return ans;
}
int main() {
    int k;
    scanf("%d%d",&n,&k);
    int i;
    int x,y;
    for(i=1; i<=k; i++) {
        scanf("%d%d",&x,&y);
        edge++;
        add(x,y+n);
    }
    printf("%d\n",work());
    return 0;
}

泥泞的牧场(今天考试题): 建二分图,A部是所有横着的板子,B部是所有竖着的板子,然后对于所有泥坑,把他相关的两个板子连起来,这样选择一个点就代表选择了一块板子,最小点覆盖就相当于用最小的板子数来覆盖所有泥坑了

4、2—SAT
(1)奇怪的,我不懂的定义 SAT是Satisfiability(适应性)的缩写,SAT问题(适应性问题)指的是给出一些条件(元素经过逻辑运算的结果,如x1 andx2 or x3 xor x4 = a),问是否存在一种合法的方案使得其满足所有的条件。SAT问题已经被证明是一个NP完全问题

https://baike.baidu.com/item/NP%E5%AE%8C%E5%85%A8%E9%97%AE%E9%A2%98/4934286?fr=aladdin
2-SAT问题是一种特殊的SAT问题,它限制了每个表达式当中最多有两个未知量。2-SAT问题已经可以在多项式复杂度内求出100%正确解

(2)一些逻辑运算的转化: 为了解决2-SAT问题,我们可以把给出的二元关系式进行一些转换,变成形如“若A取值为x则B必须取值为y”这样的条件。

为了叙述方便,我们拿取值为0和1举例子
A&B=0 -> 若A取1则B必须取0,若B取1则A必须取0
A|B=1 ->若A取0则B必须取1,若B取0则A必须取1
A^B=1 -> …
对称性 对于特殊的限制条件,例如A=1(A&B=1),我们可以构建“若A取0则A必须取1”这样的限制条件

(3)建图: 对于每种元素,把它拆成两个点a[0],a[1]分别代表两种取值,那么对于条件“若A取x则B必须取y“,则从A[x]向B[y]连一条边。那么在图中,如果P能到Q,则代表“若P成立,则Q一定成立”。

那么如果a[0]连回到了a[1]或a[1]连到了a[0],则矛盾。(用Tarjan判断) 如果没有这种情况,就一定有解。 (证明略)

(4)判定某个元素的取值是否确定: 若a[0]可选,则加入边(a[1],a[0])后,依然合法。 若a[1]可选,则加入边(a[0],a[1])后,依然合法。 若两者皆合法,则取值不确定
(5)另一种求可行解的方法: 从1到n枚举元素,枚举取值,若取值合法,则继续,否则转到另外一种取值。 时间复杂度O(nm),不过可以用来求字典序最小/大的解。
例题

[JSOI2010]满汉全席 直接放代码吧,bzoj

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
int T,n,m;
int cnt,ind,scc,top;
int last[1005],dfn[1005],low[1005],q[1005],belong[1005];
bool inq[1005];
struct edge {
    int to,next;
} e[20005];
void write() {
    for(int i=1; i<=n; i++)
        if(belong[2*i]==belong[2*i-1]) {
            puts("BAD");
            return;
        }
    puts("GOOD");
}
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int get() {
    int x;char c=getchar();
    while(c!='m'&&c!='h')c=getchar();
    if(c=='m')x=read()*2;
    else x=read()*2-1;
    return x;
}
void add(int u,int v) {
    e[++cnt].to=v;
    e[cnt].next=last[u];
    last[u]=cnt;
}
void readd() {
    int x=get(),y=get(),xp,yp;
    if(x%2==0)xp=x--;
    else xp=x++;
    if(y%2==0)yp=y--;
    else yp=y++;
    add(xp,y);
    add(yp,x);
}
void init() {
    top=ind=cnt=scc=0;
    scanf("%d%d", &n, &m);
    for(int i=1; i<=2*n; i++)
        last[i]=dfn[i]=0;
    for(int i=1; i<=m; i++)readd();
}
//读入输出部分结束 
//tarjan 
void tarjan(int x) {
    low[x]=dfn[x]=++ind;
    inq[x]=1;
    q[++top]=x;
    for(int i=last[x]; i; i=e[i].next)
        if(!dfn[e[i].to]) {
            tarjan(e[i].to);
            low[x]=min(low[x],low[e[i].to]);
        } else if(inq[e[i].to])
            low[x]=min(low[x],dfn[e[i].to]);
    if(low[x]==dfn[x]) {
        scc++;
        int now=0;
        while(now!=x) {
            now=q[top--];
            belong[now]=scc;
            inq[now]=0;
        }
    }
}
int main() {
    scanf("%d", &T);
    while(T--) {
        init();
        for(int i=1; i<=2*n; i++)
            if(!dfn[i])tarjan(i);
        write();
    }
    return 0;
}

[Usaco2011 Jan]奶牛议会
还是挂代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cctype>
#define ll long long
#define idg isdigit
#define rep(i,a,b) for(ll i=a;i<=b;i++)
#define dep(i,a,b) for(ll i=a;i>=b;i--)
#define rd1 inline ll read(){ll x=0,f=1;char ch=getchar();
#define rd2 for(;!idg(ch);ch=getchar())if(ch=='-')f=-1;
#define rd3 for(;idg(ch);ch=getchar())x=x*10+ch-'0';return x*f;}
#define fastread rd1 rd2 rd3
#define rd(x) x=read()
#define fin(x) freopen(x".in","r",stdin)
#define fout(x) freopen(x".out","w",stdout)
#define ll unsigned long long
using namespace std;
fastread
int n,m,cnt;
int last[2005],ans[2005];
bool mark[2005];
char ch[3]= {'?','N','Y'};
struct edge {
    int to,next;
} e[8005];
int get() {
    int x=read();char c=getchar();
    while(c!='Y'&&c!='N')c=getchar();
    if(c=='Y')x=x*2-1;
    else x=x*2;
    return x;
}
void insert(int u,int v) {
    e[++cnt].to=v;
    e[cnt].next=last[u];
    last[u]=cnt;
}
void dfs(int x) {
    mark[x]=1;
    for(int i=last[x]; i; i=e[i].next)
        if(!mark[e[i].to])dfs(e[i].to);
}
bool check(int x) {
    memset(mark,0,sizeof(mark));
    dfs(x);
    rep(i,1,n)if(mark[2*i]&&mark[2*i-1])return 0;
    return 1;
}
int main() {
    n=read(),m=read();
    rep(i,1,m) {
        int a=get(),b,c=get(),d;
        if(a&1)b=a+1;else b=a-1;
        if(c&1)d=c+1;else d=c-1;
        insert(b,c),insert(d,a);
    }
    rep(i,1,n) {
        bool p=check(2*i-1);
        bool q=check(2*i);
        if(!p&&!q)return puts("IMPOSSIBLE"),0;
        else if(p&&q)ans[i]=0;
        else if(!p)ans[i]=1;
        else ans[i]=2;
    }
    rep(i,1,n)printf("%c",ch[ans[i]]);
    return 0;
}

二、考试

1、str
大水题,双指针维护,O(n)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cctype>
#include<queue>
#include<vector>
#define ll long long
#define idg isdigit
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define fin(x) freopen(x".in","r",stdin)
#define fout(x) freopen(x".out","w",stdout)
#define wxh cout<<"wxh"<<endl;
using namespace std;
char ch[2000005];
int a[2000005],l,r,ans,len,num[26];
ll init;
void add(int x) {
    init|=(1<<x);
}
bool check() {
    if(init==67108863)return 1;
    return 0;
}
bool check2() {
    if(num[a[l]]>1)return 1;
    return 0;
}
int main() {
//  freopen("test.txt","r",stdin);
    fin("str");fout("str");
    gets(ch);
    len=strlen(ch);
    if(len<26)return printf("QwQ\n"),0;
    rep(i,0,len-1)a[i+1]=ch[i]-'A';
    l=1,r=1;
    num[a[r]]++,add(a[r]);
    while(!check()&&r<=len)num[a[++r]]++,add(a[r]);
    if(r>len)return printf("QwQ\n"),0;
    while(check2())num[a[l++]]--;
    num[a[--l]]++;
    ans=r-l+1;
    while(r<=len) {
        while(check2())num[a[l++]]--;
        ans=min(ans,r-l+1);
        if(r==len)break;
        while(!check2()&&r<=len)num[a[++r]]++;
    }
    printf("%d\n", ans);
    return 0;
}

2、game
呜呜呜,二分写挂。。。
先用pow(x,1/3)求出n*m的三次根号,再判断是否是整数以及n和m是否整除它。若都满足则为Yes,否则为No
证明显然

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cctype>
#define ll long long
#define idg isdigit
#define rep(i,a,b) for(ll i=a;i<=b;i++)
#define dep(i,a,b) for(ll i=a;i>=b;i--)
#define rd1 inline ll read(){ll x=0,f=1;char ch=getchar();
#define rd2 for(;!idg(ch);ch=getchar())if(ch=='-')f=-1;
#define rd3 for(;idg(ch);ch=getchar())x=x*10+ch-'0';return x*f;}
#define fastread rd1 rd2 rd3
#define rd(x) x=read()
#define fin(x) freopen(x".in","r",stdin)
#define fout(x) freopen(x".out","w",stdout)
using namespace std;
fastread
ll n,m,a[1000],b[1000];
ll get(ll x){
    int l=0,r=1e6;
    for(ll mid;l+1<r;){
        mid=(l+r)>>1;
        if(mid*mid*mid<x)l=mid;
        else r=mid;
    }
    return r;
}
int main(){
//  freopen("test.txt","r",stdin);
    fin("game");fout("game");
    int T=read();
    while(T--){
        n=read(),m=read();
        ll mx=n*m;
        ll x=get(mx);
        if(x*x*x!=mx||n%x||m%x)
            printf("No\n");
        else printf("Yes\n");
    }
    return 0;
}

3、cover
上午讲过的水题,不做叙述

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cctype>
#include<queue>
#include<vector>
#define ll long long
#define idg isdigit
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define fed(i,j) for(int i=head[j];i;i=e[i].nxt)
#define rd1 inline int read(){int x=0,f=1;char ch=getchar();
#define rd2 for(;!idg(ch);ch=getchar())if(ch=='-')f=-1;
#define rd3 for(;idg(ch);ch=getchar())x=x*10+ch-'0';return x*f;}
#define fastread rd1 rd2 rd3
#define rd(x) x=read()
#define fin(x) freopen(x".in","r",stdin)
#define fout(x) freopen(x".out","w",stdout)
using namespace std;
fastread
//最小点覆盖=最大匹配 
int n,m,matching[100005],ans=0;
int xnum,ynum,a[55][55],b[55][55];
char s[55][55];bool use[100005];
struct edge{
    int t,nxt;
}e[100005];
int head[100005],tot=1;
void add(int u,int v){
    e[++tot]=(edge){v,head[u]};
    head[u]=tot;
}
bool match(int x){
    fed(i,x)if(!use[e[i].t]){
        use[e[i].t]=1;
        if(!matching[e[i].t]||match(matching[e[i].t])){
            matching[e[i].t]=x;
            return 1;
        }
    }
    return 0;
}
int main(){
//  freopen("test.txt","r",stdin);
    fin("cover");fout("cover");
    n=read(),m=read();
    rep(i,1,n)scanf("%s", s[i]+1);
    rep(i,1,n)rep(j,1,m)if(s[i][j]=='*'){
        if(j>1&&s[i][j-1]=='*')a[i][j]=a[i][j-1];
        else a[i][j]=++ynum;
        if(i>1&&s[i-1][j]=='*')b[i][j]=b[i-1][j];
        else b[i][j]=++xnum;
    }
    rep(i,1,n)rep(j,1,m)if(s[i][j]=='*')
        add(a[i][j],b[i][j]);
    rep(i,1,ynum){
        memset(use,0,sizeof(use));
        if(match(i))ans++;
    }
    printf("%d\n", ans);
    return 0;
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
应用背景为变电站电力巡检,基于YOLO v4算法模型对常见电力巡检目标进行检测,并充分利用Ascend310提供的DVPP等硬件支持能力来完成流媒体的传输、处理等任务,并对系统性能做出一定的优化。.zip深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值