0416總結

校園網絡

1
5
2 4 3 0
4 5 0
0
0
1 0
樣例輸出
2
#include
#include
#include
#include
#define maxn 102
using namespace std;
vector G[maxn],G2[maxn];
vector s;//棧
int vis[maxn],
    sccno[maxn],                            //標記頂點所屬的連通分量
    scc_cnt;                                 //記錄有幾個強連通分量
void dfs1(int u)
{
    if(vis[u]) return ;                     //頂點遍歷過則返回
    vis[u] = 1;
    for(int i=0; i=0; i--)if( !sccno[s[i]] ){//找強連通分量,找過了則不用找了
        scc_cnt++;                          //記錄找到連通分量的個數
        dfs2(s[i]);
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    int i,j,T,n,u,ver;
    int in0[maxn],out0[maxn];
    cin>>T;
    while(T--)
    {
        cin>>n;
        for(i=1; i<=n; i++)
        for(j=1; j<=n; j++){
            cin>>ver;
            if(ver==0)break;
            G[i-1].push_back(ver-1); //原圖
            G2[ver-1].push_back(i-1);//逆向圖
        }
        find_scc(n);                 //求連通分量
        for(i=1; i<=scc_cnt; i++)in0[i] = out0[i] = 1;//同一個連通分量所有點看成一個點
        for(u=0; u
#include
#include
using namespace std;
int m;
bool map[110][110];
bool instack[110];
bool used[110];
bool income[110];
bool outcome[110];
int color[110];
int color_num;
int nodeNum[110];
int low[110];
int num;
stack Stack;

void dfs(int node)
{
	used[node] = 1;
	nodeNum[node] = ++num;
	low[node] = num;
	Stack.push(node);
	instack[node] = 1;

	int i;
	for(i = 1; i <= m; i++)
	{
		if(map[node][i] == 1)
		{
			if(used[i] == 1)
			{
				if(instack[i] == 1)
				{
					low[node] = low[node] > low[i] ? low[i] : low[node];
				}
			}
			else
			{
				dfs(i);
				low[node] = low[node] > low[i] ? low[i] : low[node];
			}
		}
	}
	if(low[node] == nodeNum[node])
	{
		while(!Stack.empty())
		{
			int top = Stack.top();
			Stack.pop();
			instack[top] = 0;
			color[top] = color_num;
			if(top == node)
			{
				color_num++;
				break;
			}
		}
	}
}
void tarjan(int * in, int * out)
{
	int i;
	for(i = 0; i <= m; i++)
	{
		instack[i] = 0;
		used[i] = 0;
		income[i] = 0;
		outcome[i] = 0;
		color[i] = 0;
		nodeNum[i] = 0;
		low[i] = 0;
	}
	color_num = 1;
	num = 0;
	for(i = 1; i <= m; i++)
	{
		if(used[i] == 0)
		{
			dfs(i);
		}
	}
	int j;
	for(i = 1; i <= m; i++)
	{
		for(j = 1; j <= m; j++)
		{
			if(map[i][j])
			{
				if(color[i] != color[j])
				{
					income[color[j]] ++;
					outcome[color[i]]++;
				}
			}
		}
	}
	int flag_in = 0;
	int flag_out = 0;
	for(i = 1; i < color_num; i++)
	{
		if(income[i] == 0)
			flag_in ++;
		if(outcome[i] == 0)
			flag_out++;
	}
	*in = flag_in;
	*out = flag_out;

}
int main()
{
//	freopen("in.txt", "r", stdin);
	int t;
	scanf("%d", &t);
	while(t--)
	{
		memset(map, 0, sizeof(map));
		scanf("%d", &m);
		int i;
		int ai;
		for(i = 1; i <= m; i++)
		{
			while(scanf("%d", &ai), ai != 0)
			{
				map[i][ai] = 1;
			}
		}
	
		int in, out;
		tarjan(&in, &out);
		if(in == 1 && out == 1)
			printf("0\n");
		else
			printf("%d\n", in > out? in : out);
	}
	return 0;
}
着色

1組數

6點  8條線

1
6 8
1 2
1 3
2 4
2 5
3 4
3 6
4 6
5 6
輸出

最多3個黑點

編號分別爲 1 4 5

#include
#include
int max,n,color[101],black[101],map[101][101];
int dfs(int x,int num)
{int i,f=1;
 if (max
#include 
#include
#define NMAX 110
bool path[NMAX][NMAX];
int n, mmax;
int dp[NMAX];
bool v[NMAX];
int seq[NMAX], seq_pos;
//seq記錄最大團集合
bool dfs(int pos, int size)
{
    int i, j, unvis;
    bool tv[NMAX];
    unvis = 0;
    for (i=pos; i mmax)
        {
            mmax = size;
            seq_pos = 0;
            seq[ seq_pos ++] = pos+1;
            return true;
        }
        return false;
    }
    for (i=pos; i < n && unvis > 0 ; i++)
    {
        if (!v[i])
        {
            if (unvis + size <= mmax || dp[i] + size <= mmax)
            {
                return false;
            }
            v[i] = true;//U = U\{vi}
            unvis --;
            memcpy(tv, v, sizeof(v));
            for (j=0; j=0; i--)
    {
        for (j=0; j

The Perfect Stall

5 5
2 2 5
3 2 3 4
2 1 5
3 1 2 5
1 2
Sample Output
4

#include

using namespace std;

int n,m,match[300]; //二分圖的兩個集合分別含有n和m個節點

bool visit[300],map[210][210];  //map存儲圖G的鄰接矩陣

bool dfs(int k)

{

    int t;

    for(int i=1;i<=m;i++)

        if(map[k][i] && !visit[i])  //如果節點i與k相鄰並且未被查找過

        {

            visit[i]=true;  //標記i爲已查找過

            if(match[i]==-1 //如果i未在前一個匹配M中

               || dfs(match[i])) //i在匹配M中,但是從與i相鄰的節點出發可以有增廣路

            {

                match[i]=k; //記錄查找成功記錄

                return true;

            }

        }

    return false;

}

int main()

{

       int p,q,r,i,j;

    while(cin>>n>>m)

       {

      memset(map,0,sizeof(map));

    int s=0;  

       for( i=1;i<=n;i++)

       {

              cin>>p;

              for(j=1;j<=p;j++)

              {

                     cin>>q;

                  map[i][q]=1;

              }

       }

    memset(match,-1,sizeof(match));

    for( i=1;i<=n;i++)    //以二分集中的較小集n進行匹配較優

    {

        memset(visit,false,sizeof(visit));

        if (dfs(i)) s++;    //s爲匹配數

    }

       cout<
#include
#include

using namespace std;

const int maxn=210;

int map[maxn][maxn];
int vis[maxn];
int match[maxn];
int n,m;

int dfs(int x)
{
    int i;
    for(int i=1;i<=m;i++)
    {
        if(vis[i]==-1&&map[x][i])
        {
            vis[i]=1;
            if(match[i]==-1||dfs(match[i]))
            {
                match[i]=x;
                return 1;
            }
        }
    }
    return 0;
}

int maxmatch()
{
    int i,sum=0;
    for(i=1;i<=n;i++)
    {
        memset(vis,-1,sizeof(vis));
        if(dfs(i)) sum++;
    }
    return sum;
}

int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(map,0,sizeof(map));
        memset(match,-1,sizeof(match));
        for(int i=1;i<=n;i++)
        {
            int a,b;
            scanf("%d",&a);
            for(int j=0;j
一筆畫問題
2
4 3
1 2
1 3
1 4
4 5
1 2
2 3
1 3
1 4
3 4
樣例輸出
No
Yes
#include
#include
int father[1010],ans[1010];
void ini()
{
    for(int i=0;i<=1010;i++)
        father[i]=i;
}
int find(int x)
{
     if(father[x]==x)
        return x;
     else
        return father[x]=find(father[x]);
}
int main()
{
     int ncases,n,m,x,y,i,count,jdcount;
     scanf("%d",&ncases);
     while(ncases--)
     {
          memset(ans,0,sizeof(ans));
          ini();
          count=jdcount=0;
          scanf("%d %d",&n,&m);
          for(i=1;i<=m;i++)
          {
               scanf("%d %d",&x,&y);
               ans[x]++;   ans[y]++;
               x=find(x);  y=find(y);
               if(x!=y)
                    father[x]=father[y];
          }
          for(i=1;i<=n;i++)
              if(find(i)==i)
                count++;//判斷連通性
          for(i=1;i<=n;i++)
              if(ans[i]%2==1)
                  jdcount++;//奇點個數
          if((jdcount==0||jdcount==2)&&count==1)
              printf("Yes\n");
          else
              printf("No\n");
     }
}
#include
#include
#include
int father[1005];
int degree[1005];
int find(int x)
{
    if(x!=father[x])
        father[x]=find(father[x]);
    return father[x];
}
void merge(int x,int y)
{
    x=find(x);
    y=find(y);
    if(x!=y)
        father[x]=y;
}
int main()
{
    int i,a,b,n,p,q,cnt,dnt; 
    scanf("%d",&n);
    while(n--){
        cnt=dnt=0;
        memset(degree,0,sizeof(degree));
        scanf("%d%d",&p,&q);
        for(i=1;i<=p;i++)
            father[i]=i;
        while(q--){
            scanf("%d%d",&a,&b);
            if(a==b) continue;
            degree[a]++;
            degree[b]++;
            merge(a,b);
        }
        for(i=1;i<=p;i++){
            if(father[i]==i)
                cnt++;
            if(degree[i]&1)
                dnt++;
        }
        if(cnt==1&&(dnt==0||dnt==2))
            puts("Yes");
        else
            puts("No");
    }
    //system("pause");
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章