二分图

https://vjudge.net/contest/286149#problem/G 专题连接

1.判二分图

The Accomodation of Students

 

//bfs法
//先把一个点染色,然后把他周围联通的所有节点染色,如果染得颜色冲突,则不能形成二分图,如果没有染色,则染一个相反的颜色。 #include
<cstdio> #include<algorithm> #include<cstring> #include<vector> #include<queue> using namespace std; const int maxm = 205; int line[maxm][maxm], used[maxm], nxt[maxm]; int col[maxm]; int n, m, u, v; bool fid(int x) { for(int i = 1; i <= n; i++) { if(line[x][i] && !used[i]) { used[i] = 1; if(nxt[i] == 0 || fid(nxt[i])) { nxt[i] = x; return true; } } } return false; } int match() { int sum = 0; for(int i = 1; i <= n; i++) { memset(used, 0, sizeof(used)); if(fid(i)) sum++; } return sum; } bool bfs() { for(int i = 1; i <= n; i++) { if(col[i] == -1) { col[i] = 0; queue<int> q; q.push(i); while(!q.empty()) { int k = q.front(); q.pop(); for(int j = 1; j <= n; j++) { if(line[k][j] && col[j] == col[k]) { return 0; } if(line[k][j] && col[j] == -1) { col[j] = 1 - col[k]; q.push(j); } } } } } return 1; } int main() { while(~scanf("%d%d", &n, &m)) { memset(col, -1, sizeof(col)); memset(line, 0, sizeof(line)); memset(nxt, 0, sizeof(nxt)); while(m--) { scanf("%d%d", &u, &v); line[u][v] = line[v][u] = 1; } if(!bfs()) { printf("No\n"); continue; } printf("%d\n", match() / 2); } return 0; }
#include<vector>
 
using namespace std;
 
 
static const int MAX = 10000;
vector<int> G[MAX]; //
int V;  //顶点数量
int color[MAX]; //每个点的颜色(1,-1)
 
//将顶点v染成颜色c,成功染色返回true,否则返回false
bool dfs(int v, int c)
{
    color[v] = c;
    for (int i = 0; i < G[v].size(); i++)
    {
        if (color[G[v][i]] == c)
            return false;   //相邻的点的颜色相同
        if (color[G[v][i]] == 0 && !dfs(G[v][i], -c))
            return false;
    }
    //所有点都染好颜色了
    return true;
}
 
void solve()
{
    for (int i = 0; i < V; i++)
        if (color[i] == 0)
            if (!dfs(i, 1)) //未染色
            {
                printf("No\n");
                return;
            }    
    printf("Yes\n");
}

https://blog.csdn.net/flynn_curry/article/details/52966283

这个讲了最大匹配,最小点覆盖,最小边覆盖,最大独立自己等等。

Courses

 二分图邻接举证模板,复杂度势N* M;

题意:n个课,m个人,保证取出所有课,所有课对应一个人。

输入能上这个课的人的编号;例如 3 1 2 3 如果是在第一行,表示能上第一堂课的人有3个,分别是1,2,3.

显示建二分图,左边表示课程,右边表示学生,如果学生能上某个可就连一条边,然后求最大匹配。

#include<cstdio>
#include<algorithm>
#include<cstring>


using namespace std;
const int maxm = 305;
int line[maxm][maxm], used[maxm], nxt[maxm];
int t, p, n, m, u, v;

bool fid(int x) {
for(int i = 1; i <= n; i++) {
    if(line[x][i] && !used[i]) {
        used[i] = 1;
        if(nxt[i] == 0 || fid(nxt[i])) {
            nxt[i] = x;
            return true;
        }
    }
}
return false;
}
int match() {
int sum = 0;
for(int i = 1; i <= p; i++) {
    memset(used, 0, sizeof(used));
    if(fid(i)) sum++;
}
return sum;
}
int main() {
scanf("%d", &t);
while(t--) {
    scanf("%d%d", &p, &n);
    memset(line, 0, sizeof(line));
    memset(nxt, 0, sizeof(nxt));
    for(int i = 1; i <= p; i++) {
        scanf("%d", &m);
        while(m--) {
            scanf("%d", &v);
            line[i][v] = 1;
        }

    }
    if(p > n) {
        printf("NO\n");
        continue;
    }

if(match() == p) {
    printf("YES\n");
}
else {
    printf("NO\n");
}
}

return 0;
}
//邻接表版本。
#include<cstdio> #include<algorithm> #include<cstring> #include<vector> using namespace std; const int maxm = 605; vector<int> ve[maxm]; int match[maxm]; bool used[maxm]; int t, p, n, m; void add(int u, int v) { ve[u].push_back(v); ve[v].push_back(u); } bool dfs(int v) { used[v] = 1; for(int i = 0; i < ve[v].size(); i++) { int u = ve[v][i]; int w = match[u]; if(w < 0 || (!used[w] && dfs(w) )) { match[v] = u;; match[u] = v; return true; } } return false; } int ma() { int res = 0; memset(match, -1, sizeof(match)); for(int i = 1; i <= p; i++) { if(match[i] < 0) { memset(used, 0, sizeof(used)); if(dfs(i)) { res++; } } } return res; } int main() { scanf("%d", &t); while(t--) { scanf("%d%d", &p, &n); for(int i = 1; i <= p + n; i++) { ve[i].clear(); } int v; for(int i = 1; i <= p; i++) { scanf("%d", &m); while(m--) { scanf("%d", &v); add(i, v + p); } }
//建图过程中把课程编号为1-p,把学生编号为p + 1, p + n;然后进行二分图匹配。
if(p > n) { printf("NO\n"); continue; } if(ma() == p) { printf("YES\n"); } else { printf("NO\n"); } } return 0; }

 

https://wenku.baidu.com/view/63c1a01655270722192ef7c3.html

https://blog.csdn.net/juncoder/article/details/38346193

建图方式的博客。主要是建图。

转载于:https://www.cnblogs.com/downrainsun/p/10490591.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于PyTorch的Embedding和LSTM的自动写诗实验LSTM (Long Short-Term Memory) 是一种特殊的循环神经网络(RNN)架构,用于处理具有长期依赖关系的序列数据。传统的RNN在处理长序列时往往会遇到梯度消失或梯度爆炸的问题,导致无法有效地捕捉长期依赖。LSTM通过引入门控机制(Gating Mechanism)和记忆单元(Memory Cell)来克服这些问题。 以下是LSTM的基本结构和主要组件: 记忆单元(Memory Cell):记忆单元是LSTM的核心,用于存储长期信息。它像一个传送带一样,在整个链上运行,只有一些小的线性交互。信息很容易地在其上保持不变。 输入门(Input Gate):输入门决定了哪些新的信息会被加入到记忆单元中。它由当前时刻的输入和上一时刻的隐藏状态共同决定。 遗忘门(Forget Gate):遗忘门决定了哪些信息会从记忆单元中被丢弃或遗忘。它也由当前时刻的输入和上一时刻的隐藏状态共同决定。 输出门(Output Gate):输出门决定了哪些信息会从记忆单元中输出到当前时刻的隐藏状态中。同样地,它也由当前时刻的输入和上一时刻的隐藏状态共同决定。 LSTM的计算过程可以大致描述为: 通过遗忘门决定从记忆单元中丢弃哪些信息。 通过输入门决定哪些新的信息会被加入到记忆单元中。 更新记忆单元的状态。 通过输出门决定哪些信息会从记忆单元中输出到当前时刻的隐藏状态中。 由于LSTM能够有效地处理长期依赖关系,它在许多序列建模任务中都取得了很好的效果,如语音识别、文本生成、机器翻译、时序预测等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值