• poj 1386 判断欧拉图存在


    网上转载,有点偷懒

    //求欧拉回路,注意欧拉图的性质
    //构图的思想是以单词的首字母和末字母作为结点构图,将单词作为一条有向边
    //(A)----acm------>(M)-----malform---->(M)------mouse----->(E)
    //1、第一步是要先对图的连通性进行判断,即去掉边的方向,看图是否连通
    //我看了数据规模才26,我就偷懒写个Floyd水下算了
    //2、第二步就是根据欧拉图的性质进行判断就可以了,判断存在欧拉道路或存在欧拉回路
    //(1)有向图G为欧拉图(存在欧拉回路),当且仅当G的基图连通,且所有顶点的入度等于出度。
    //(2)有向图G为半欧拉图(存在欧拉道路),当且仅当G的基图连通,且存在顶点u的入度比出度大1、v的入度比出度小1,其它所有顶点的入度等于出度。
    #include<iostream>
    #include<vector>
    using namespace std;
    int indeg[26],outdeg[26],vis[26];
    int G[26][26];
    char word[1010];
    vector<int> letter;
    int t,m;
    bool checkEulerPath()
    {
    	int st,ed;
    	st = ed = 0;
    	bool circle = 1;
    	for(int i = 0;i < letter.size();++i)
    	{
    		int x = letter[i];
    		if(indeg[x] - outdeg[x] == 1)	
    		{
    			++ed;
    			circle = 0;
    		}
    		else if(outdeg[x] - indeg[x] == 1)	
    		{
    			++st;
    			circle = 0;
    		}
    		else if(outdeg[x] != indeg[x])	return false;
    	}
    	if(circle)	return true;
    	if(st == 1 && ed == 1)	return true;
    	return false;
    }
    void Floyd()
    {
    	for(int k = 0;k < 26;++k)
    		for(int i = 0;i < 26;++i)
    			for(int j = 0;j < 26;++j)
    				if(G[i][k] && G[k][j])	
    					G[i][j] = 1;
    }
    bool checkConnect()
    {
    	Floyd();
    	for(int i = 0;i < letter.size();++i)
    		for(int j = 0;j < letter.size();++j)
    		{
    			int x = letter[i];
    			int y = letter[j];
    			if(!G[x][y])	return false;
    		}
    	return true;
    }
    int main()
    {
    	//freopen("in.txt","r",stdin);
    	scanf("%d",&t);
    	while(t--)
    	{
    		scanf("%d",&m);
    		letter.clear();
    		memset(indeg,0,sizeof(indeg));
    		memset(outdeg,0,sizeof(outdeg));
    		memset(G,0,sizeof(G));
    		memset(vis,0,sizeof(vis));
    		while(m--)
    		{
    			scanf("%s",word);
    			int last = word[strlen(word) - 1] - 'a';
    			int first = word[0] - 'a';
    			G[first][last] = G[last][first] = 1;
    			indeg[last]++;
    			outdeg[first]++;
    			if(!vis[last])	
    			{
    				letter.push_back(last);
    				vis[last] = 1;
    			}
    			if(!vis[first])
    			{
    				letter.push_back(first);
    				vis[first] = 1;
    			}
    		}
    		if(checkConnect() && checkEulerPath())	
    			printf("Ordering is possible.\n");
    		else 
    			printf("The door cannot be opened.\n");
    	}
    	return 0;
    }
    
  • 相关阅读:
    实现字符串的翻转
    svn的安装和配置
    insert php code test
    收集的一些题
    制作多选框,并通过PHP获取多选框数据
    laravel 导出
    laravel migrate 指定文件执行
    laravel facebook等第三方授权登录
    Mysql 时间字段(加上或者减去一段时间)
    配置指定日志记录目录
  • 原文地址:https://www.cnblogs.com/steady/p/1942657.html
Copyright © 2020-2023  润新知