D - Unique Path

D - Unique Path

题意

已知有一个图有n个点m条边

已知q条线索,以u,v,x的格式给出

x = = 0 x==0 x==0,表示u,v之间仅存在一条路径

否则,表示u,v之间存在多条路经

问,该图是否存在


思路

考虑计算出若该图存在,所需的最少边数和最多边数

  • 可以先将所有0线索连起来(并查集)

  • 显然,我们得到多个连通块,且每一个都是树

  • 而树和树之间是可以相连的,但只可以连一条线(因为他们之间没有0关系)

  • 考虑1线索,他需要将孤立点和连通块串在一个环上

  • 最少的情况:从连通块和孤立点组成环,且至少有三个点(整个图要连通

  • 最多的情况:将连通块和孤立点,全部构成完全图


代码

typedef pair<int, int> pii;
const int maxn = 1e5 + 5;
vector<pii> opt[2];
int f[maxn]; //链的并查集
bool vis[maxn];
int find(int x)
{
    return x == f[x] ? x : f[x] = find(f[x]);
}
set<int> Set;
int main()
{
    long long nn, mm;
    scanf("%lld%lld", &nn, &mm);
    int q;
    scanf("%d", &q);
    int u, v, x;
    for (int i = 1; i <= q; i++) {
        scanf("%d%d%d", &u, &v, &x);
        opt[x].push_back(make_pair(u, v));
    }
    if (nn == 2) {
        if (opt[0].size() == 1 && q == 1)
            printf("Yes\n");
        else
            printf("No\n");
        return 0;
    }
    for (int i = 0; i < nn; i++)
        f[i] = i;
    for (auto it : opt[0]) {
        vis[it.first] = vis[it.second] = true;
        f[find(it.first)] = find(it.second);
    }
    long long sum = 0, num = 0;
    for (int i = 0; i < nn; i++)
        if (vis[i]) {
            sum++;
            if (find(i) == i)
                num++;
        }
    for (auto it : opt[1]) {
        if (vis[it.first] && vis[it.second]) {
            if (find(it.first) == find(it.second)) {
                printf("No\n");
                return 0;
            }
        }
    }
    long long lone = nn - sum;
    long long m1 = 0, m2 = 0;
    if (opt[1].size() == 0) {
        m1 = sum - num;
        m2 = sum - num + (lone + num) * (lone + num - 1) / 2;
    } else {
        m1 = sum - num + max(3LL, num + lone);
        m2 = (num + lone) * (num + lone - 1) / 2 + sum - num;
    }
    if (mm >= m1 && mm <= m2) {
        printf("Yes\n");
    } else
        printf("No\n");
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这段代码主要是用于处理图像分类数据,并使用图最小最大化算法进行图像分类。下面是对代码的解释: 1. `clear clc warning off;`: 清空命令行窗口并关闭警告信息; 2. `path = pwd; addpath(genpath(path));`: 将当前路径及其子文件夹添加到MATLAB搜索路径中; 3. `dataName{1} = 'flower17';`: 设置图像数据集的名称,此处为flower17; 4. `for name = 1`: 循环遍历数据集中的每个图像; 5. `load(['./',dataName{name},'_Kmatrix']);`: 加载预处理后的图像数据,其中_Kmatrix是图像的相似性矩阵,保存在.mat文件中; 6. `Y(Y==-1)=2;`: 将标签中的-1替换为2,以便后续处理; 7. `numclass = length(unique(Y));`: 计算图像数据集中的类别数; 8. `numker = size(KH,3); num = size(KH,1);`: 计算图像相似性矩阵的大小,其中numker为矩阵的张数,num为矩阵的行数; 9. `KH = remove_large(KH); KH = knorm(KH); KH = kcenter(KH); KH = divide_std(KH);`: 对图像相似性矩阵进行预处理,包括去除异常值、归一化、中心化、标准化等; 10. `options.seuildiffsigma=1e-4;`: 设置图最小最大化算法的参数,即权重变化的停止条件; 11. `options.goldensearch_deltmax=1e-1; options.numericalprecision=1e-16;`: 设置算法的一些数值参数,包括黄金分割法的初始精度和权重的数值精度; 12. `options.firstbasevariable='first'; options.nbitermax=500; options.seuil=0; options.seuilitermax=10; options.miniter=0;`: 设置算法的一些参数,包括选择基础变量的方法、最大迭代次数、权重阈值、迭代次数阈值等; 13. `options.threshold = 1e-4;`: 设置算法的收敛阈值; 14. `qnorm = 2;`: 计算范数,一般默认为2; 15. `[S,Sigma,obj] = graph_minmax(KH, options);`: 使用图最小最大化算法对图像相似性矩阵进行聚类,并返回聚类结果; 16. `S1 = (S + S') / 2; D = diag(1 ./ sqrt(sum(S1))); L = D * S1 * D;`: 将聚类结果转化为拉普拉斯矩阵,其中D为度矩阵,S1为对称邻接矩阵; 17. `[H,~] = eigs(L, numclass, 'LA');`: 对拉普拉斯矩阵进行特征值分解,获取特征向量; 18. `res= myNMIACC(H,Y,numclass);`: 计算分类精度; 19. `disp(res);`: 显示分类精度结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值