hdu 1116 欧拉通路+并查集

本文介绍了一种算法,用于判断一系列英文单词是否能够形成连续的链条,通过连接每个单词的末尾字母与下一个单词的起始字母。利用并查集判断连通性,将单词的首尾字母转化为图的边,分析顶点的出入度来确定是否存在欧拉回路或欧拉通路,从而判断单词链路的可能性。
题意:给你一些英文单词,判断所有单词能不能连成一串,前一个单词的最后一个字母和后一个单词的首字母相同则可以相连。
 

判断是否构成欧拉回路或者欧拉通路(以下是别人博客里的一段)

1.并查集判断连通

2.将每个单词取出首字母和尾字母,转换为一条边,然后加入对应的连通分量中。如果这个字母出现过,visit数组标记为true。同时起点出度加1,终点入度加1.

3.判断一下:

1)这个图必须是连通的,即根结点只有一个。如果不是,直接结束本次算法

2)如果这个图是连通的,判断每个结点的入度和出度情况。

        如果这个图是欧拉路,则每个顶点的出度等于入度。即out[i] = in[i]

如果这个图是半欧拉图,则起点的出度比入度大1,终点的入度比出度大1.其余顶点的出度等于入度。

如果满足上述条件,就可以将所有单词链接起来,否则不能。

当然,在判断出度入度的时候还有一点需要注意,那就是除了起点终点以外的顶点,出度必须等于入度(出度入度可以同时为2,即环),但是起点和终点必须保证出度和入度之差为1。

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cmath>
  4 #include<vector>
  5 #include<string.h>
  6 #include<string>
  7 
  8 using namespace std;
  9 
 10 const int MAX_N = 30;
 11 int pre[MAX_N],father[MAX_N];
 12 int iin[MAX_N],oout[MAX_N];
 13 bool visited[MAX_N];
 14 int n;
 15 
 16 void init()
 17 {
 18     for(int i = 0; i < MAX_N; i++)
 19     {
 20         pre[i] = i;
 21         iin[i]=0;
 22         oout[i]=0;
 23         father[i] = 0;
 24         visited[i]=0;
 25     }
 26 }
 27 
 28 int find_root(int x)
 29 {
 30     int r = x;
 31     while(pre[r]!=r)
 32         r = pre[r];
 33     
 34     int i = x,j;
 35     while(i!=r)
 36     {
 37         j = pre[i];
 38         pre[i] = r;
 39         i = j;
 40     }
 41     return r;
 42 }
 43 
 44 void mix(int x,int y)
 45 {
 46     int xx = find_root(x);
 47     int yy = find_root(y);
 48     if(xx!=yy)
 49         pre[yy] = xx;
 50 }
 51 int main()
 52 {
 53     cin.sync_with_stdio(false);
 54     int t,st,en;
 55     cin>>t;
 56     while(t--)
 57     {
 58         init();
 59         cin>>n;
 60         string s;
 61         for(int i = 1; i <= n; i++)
 62         {
 63             cin>>s;
 64             st = s[0]-'a';
 65             en = s[s.length()-1]-'a';
 66             mix(st,en);
 67             oout[st]++;
 68             iin[en]++;
 69             visited[st]=1;
 70             visited[en]=1;
 71         }
 72        
 73         for(int i = 0; i < 26; i++)
 74         {
 75             if(visited[i])
 76                 father[i] = find_root(i);
 77         }
 78         int ii = 0,oo = 0, flag = 0,roots = 0,te = 0;
 79         for(int i = 0; i < 26; i++)
 80         {
 81             if(visited[i])
 82             {
 83                 if(iin[i]!=oout[i])
 84                 {
 85                     if(iin[i]-oout[i]==1)
 86                         ii++;
 87                     else
 88                         if(oout[i]-iin[i]==1)
 89                             oo++;
 90                     else
 91                     {
 92                         te++;
 93                     }
 94                 }
 95                 if(father[i]==i)
 96                     roots++;
 97                 
 98             }
 99         }
100         if(roots==1 &&((ii==0 && oo==0 && te==0)|| (ii==1 && oo==1 && te==0)))
101             flag = 1;
102         if(flag==1)
103             cout<<"Ordering is possible."<<endl;
104         else
105             cout<<"The door cannot be opened."<<endl;
106             
107         
108     }
109     return 0;
110 }

 

转载于:https://www.cnblogs.com/Xycdada/p/7374208.html

内容概要:本文介绍了一种基于双层优化的微电网系统规划设计方法,旨在通过Matlab代码实现,解决微电网在规划与运行中的多目标、多层次决策问题。该方法将优化过程分为上下两层:上层通常负责容量配置、设备选址等长期规划决策,下层则聚焦于能量管理、出力调度等短期运行优化,通过迭代交互实现全局最优。文中详细阐述了模型构建、约束条件设定、目标函数设计及求解算法实现流程,并提供了完整的Matlab代码供复现实验,有助于深入理解微电网系统的设计逻辑与优化机制。; 适合人群:具备一定电力系统基础知识和Matlab编程能力,从事新能源、微电网、综合能源系统等领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:① 学习和掌握双层优化理论在微电网规划设计中的具体应用;② 通过阅读和运行Matlab代码,复现并改进经典优化模型,用于学位论文、科研项目或实际工程方案设计;③ 深入理解微电网中分布式能源、储能与负荷的协同优化调度策略。; 阅读建议:此资源以Matlab代码实现为核心,强调理论与实践的结合。建议读者先理解双层优化的基本思想和数学模型,再结合代码逐行分析,重点关注变量定义、约束条件的代码转化以及主从问题间的迭代逻辑。鼓励在提供的代码基础上进行参数调整、场景扩展或算法改进,以深化学习效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值