列表

详情


NC50425. 相框

描述

P大的基础电路实验课是一个无聊至极的课。每次实验,T君总是提前完成,管理员却不让T君离开,T君只能干坐在那儿无所事事。
先说说这个实验课,无非就是把几根导线和某些元器件(电阻、电容、电感等)用焊锡焊接起来。
为了打发时间,T君每次实验做完后都在焊接一些诡异的东西,这就是他的杰作:
1.jpgT君不满足于焊接奇形怪状的作品,强烈的破坏欲驱使他拆掉这个作品,然后将之焊接成规整的形状。这会儿,T君正要把这个怪物改造成一个环形,当作自己的相框,步骤如下:
2.jpgT君约定了两种操作:
  1. 烧熔一个焊点:使得连接在焊点上的某些导线相分离或保持相连(可以理解为:把焊点上的导线划分为若干个类,相同类中的导线相连,不同类之间的导线相离)
  2. 将两根导线的自由端(即未与任何导线相连的一端)焊接起来。
例如上面的步骤中,先将A点烧熔,使得导线1与导线2,4点分离;再将D点烧熔,使得4,5与3,7相离;再烧熔E,使7与6,8相离;最后将1,7相连。
T君想用最少的操作来将原有的作品改造成为相框(要用上所有的导线)。

输入描述

第一行共有两个整数n和m——分别表示原有的作品的焊点和导线的数量。焊点的标号为。接下来的m行每行共有两个整数——导线两端所连接的两个焊点的标号,若不与任何焊点相连,则将这一端标号为0。
原有的作品可能不是连通的。
某些焊点可能只有一根导线与之相连,在该导线的这一端与其他导线相连之前,这些焊点不允许被烧熔。
某些焊点甚至没有任何导线与之相连,由于T君只关心导线,因此这些焊点可以不被考虑。

输出描述

只包含一个整数——表示T君需要将原有的作品改造成相框的最少步数。

示例1

输入:

6 8
1 2
1 3
3 4
1 4
4 6
5 6
4 5
1 5

输出:

4

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Java(javac 1.8) 解法, 执行用时: 221ms, 内存消耗: 29236K, 提交时间: 2021-03-14 17:28:38

import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;

public class Main {

    static class Task {


        public int[] tn(int a){
            int f[] = new int[11];
            if(a==0) {
                return new int[2];
            }
            int p = 1;
            while(a>0){
                int w = a%10;
                f[p++] = w;
                a/=10;
            }
            return Arrays.copyOf(f,p);
        }

        public int[] tt(String a){
            int f[] = new int[2010];
            int p = 1;

            for(int i=a.length()-1;i>=0;--i) {
                f[p++] = a.charAt(i)-'0';
            }
            return Arrays.copyOf(f, p);
        }



        static int rt = 0;
        static int ch[][] ;
        static int fa[];
        static int id[];
        static int mk[];
        static int ct = 1;
        static int cnt[];

        static void insert(String s,int j,int num) {
            int p = 0; // root
            for (char c : s.toCharArray()) {
                int d = c - 'a';
                if (ch[p][d] == 0) {
                    ch[p][d] = ct++;
                }
                p = ch[p][d];
                //  mk[p]+= num;
            }
            mk[p] = 1;
            // id[p] = 1 << j;
        }
        static int q[] ;
        static int q1[] ;
        static void build(){

            int s = 0; int e = 0;

            for(int i=0;i<26;++i) {
                if(ch[0][i]>0) {
                    q[e++] = ch[0][i];
                }
            }

            while(s<e){
                int c = q[s++];

//                if(id[fa[c]]>0){
//                    id[c] = id[fa[c]];
//                }
                mk[c] |= mk[fa[c]];

                for(int j=0;j<26;++j){
                    if(ch[c][j]>0){
                        fa[ch[c][j]] = ch[fa[c]][j];
                        q[e++] = ch[c][j];
                    }else{
                        ch[c][j] = ch[fa[c]][j];
                    }
                }
            }
//            for(int i=e-1;i>=0;--i){
//                if(id[q[i]]!=-1){
//                    cnt[id[q[i]]] += mk[q[i]];
//                }
//                mk[fa[q[i]]] += mk[q[i]];
//            }
        }
        static int search(String s){
            int at = 0;
            int cnt = 0;
            for(char c:s.toCharArray()){
                int to = c-'a';
                to = ch[at][to];
                int j = to;

                while(j != 0) {
                    cnt += mk[to];
                    j = fa[j];
                }
            }
            return cnt;
        }




        int p[][];double d[];int fat[];int sz[];
        int sdp[][];

        void get(int i,int j,List<Integer> li){
            if(sdp[i][j]==0) return;
            get(i,sdp[i][j],li);
            li.add(sdp[i][j]);
            get(sdp[i][j],j,li);
        }

        interface Func{
            void add(int u,int v);
        }

        int root(int f){
            return fat[f] = fat[f]!=f?root(fat[f]):f;
        }
        void combine(int x,int y){
            int rt1 = root(x);
            int rt2 = root(y);
            if(rt1!=rt2){
                fat[rt1] = rt2;
            }
        }

        int ct1 = 0;
        int to[];int ne[];
        int h[];
        void dfs(int rt,int pass){
            if(id[rt]>0){


                Func fc = (x,y)->{
                    to[ct1] =  y;
                    ne[ct1] = h[x];
                    h[x] = ct1++;
                };

                fc.add(id[pass],id[rt]);
                // fc.add(id[rt],id[pass]);
                pass = rt;
            }
            for(int i=0;i<26;++i){
                if(ch[rt][i]>0){
                    dfs(ch[rt][i], pass);
                }
            }
        }

        // edge number is small
        boolean vis[];

        public boolean spfa(int s, int n, double cut) {

            d = new double[n];
            Arrays.fill(d, -len);
            int cnt[] = new int[n];

            ArrayDeque<Integer> qu = new ArrayDeque<>();



            qu.offer(s);
            d[s] = 0;
            double tot = 0;
            boolean in[] = new boolean[n];

            while (qu.size() > 0) {
                int node = qu.poll();
                //tot -= d[node];
                in[node] = false;
                vis[node]  = true;
                for (int i = h[node]; i != -1; i = ne[i]) {
                    int v = to[i];
                    double w = wt[i] -  cut;
                    if (d[node] + w > d[v]) {
                        d[v] = d[node] + w;
                        if (++cnt[v] > n) {
                            return true;
                        }

                        if (!in[v]) {


                            tot += d[v];
                            if (!qu.isEmpty() && d[v] > d[qu.peekFirst()]) {
                                qu.offerFirst(v);
                            } else {
                                qu.offerLast(v);
                            }
//                            double x = tot / q.size();
//                            while (d[q.peekFirst()] < x) {
//                                q.offerLast(q.pollFirst());
//                            }

                        }
                    }
                }
            }

            return false;
        }

        int wt[];

        void add(int u,int v,int w){
            to[ct] = v;
            ne[ct] = h[u];
            wt[ct] = w;
            h[u] = ct++;
        }




        void g(int n,int m){

            ct = 0;
            h = new int[n];
            Arrays.fill(h,-1);
            to = new int[m];
            ne = new int[m];
            wt = new int[m];
        }

        double len =  0;

        int b = 0;
        boolean fob[];
        int[] lu;
        int tp;
        void dfs11(int rt){
            while(h[rt]!=-1){
             if(st[h[rt]]){
                 h[rt] = ne[h[rt]];
                 continue;
             }
             st[h[rt]] = true;
             int other = h[rt]^1;
             st[other] = true;

             int j =  to[h[rt]];
             int lj = wt[h[rt]];
             h[rt] = ne[h[rt]];
             dfs11(j);
             lu[tp--] =  lj;
            }
        }

        boolean st[];

    public void solve(int testNumber, InputReader in, PrintWriter out) {


                int n = in.nextInt();
                int m = in.nextInt();

                int d[]=  new int[n+1];

                fat  = new int[n+1];

                for(int j=1;j<=n;++j){
                    fat[j] = j;
                }



                for(int i =0;i<m;++i) {
                    int u  = in.nextInt();
                    int v  = in.nextInt();
                    if(root(u)!=root(v)){
                        combine(u,v);
                    }
                    d[u]++;d[v]++;
                }

                int cnt[]  = new int[n+1];
                int cnt1[]  = new int[n+1];

                TreeSet<Integer> st = new TreeSet<>();
                for(int j=0;j<=n;++j){
                    if(d[j]==0) continue;

                    int mk = root(j);

                    if(j==0){
                        cnt1[mk] += d[j];
                        st.add(mk);
                        continue;
                    }

                    if(d[j]%2==0){
                        if(d[j]>2){
                            cnt[mk]++;
                        }
                    }else{
                        if(d[j]==1){
                            cnt1[mk]++;
                        }else{
                            cnt[mk]++;
                            cnt1[mk]++;
                        }
                    }
                    st.add(mk);
                }
                int r = 0;
                if(st.size()==1){
                    int y =  st.pollFirst();
                    r =  cnt[y] + cnt1[y]/2;
                }else{

                    for(int u:st){
                        if(cnt1[u]>0) {
                            r += cnt[u] + (cnt1[u]-2)/2;
                        }else{
                            if(cnt[u]==0){
                                r++;
                            }else {
                                r += cnt[u];
                            }
                        }

                    }
                    r += st.size();



                }
                out.println(r);


            }


//        int t = in.nextInt();
//        int n = in.nextInt();
//        int m = in.nextInt();
//
//        ct = 0;
//        h = new int[n];Arrays.fill(h,-1);
//        if(t==1) {
//            to = new int[m * 2];
//            ne = new int[m * 2];
//
//            fob = new boolean[m * 2];
//        }else{
//            to = new int[m];
//            ne = new int[m];
//
//        }
//
//
//        int rd[] = new int[n];
//        int cd[] = new int[n];
//        li = new int[m];
//        tp = m-1;
//
//        int rt=  0;
//
//        for(int i=0;i<m;++i){
//            int u = in.nextInt()-1;
//            int v = in.nextInt()-1;
//            add(u,v);
//            if(t==1){
//                add(v,u);
//            }
//            cd[u]++;
//            rd[v]++;
//            rt = u;
//        }
//
//        if(t==2){
//
//            for(int i=0;i<n;++i){
//                if(rd[i]!=cd[i]){
//                    out.println("NO");return;
//                }
//            }
//        }else{
//
//            for(int i=0;i<n;++i){
//                if(((rd[i]+cd[i])%2)>0){
//                    out.println("NO");return;
//                }
//            }
//
//        }
//
//
//
//        dfs11(rt, t);
//
//
//
//        if(tp!=-1){
//            out.print("NO");
//            return;
//        }
//
//        out.println("YES");
//
//        for(int i=0;i<m;++i){
//            out.print(li[i]+ " ");
//        }




















//            int f1[][] = new int[q][3];
//
//            for(int i=0;i<q;++i){
//                for(int j=0;j<3;++j){
//                    f1[i][j] = in.nextInt();
//                }
//            }
//
//
//                int h[] = new int[n+1];
//
//                Arrays.fill(h,-1);
//
//
//                int ne[] = new int[p*2+q];
//                int to[] = new int[p*2+q];
//                int wt[] = new int[p*2+q];
//                ct = 0;
//            Func fk = (int x,int y,int z) -> {
//                to[ct] = y;
//                ne[ct] = h[x];
//                wt[ct] = z;
//                h[x] = ct++;
//            };
//
//                for(int i=0;i<p;++i){
//                    int u =  f[i][0];
//                    int v =  f[i][1];
//
//
//
//
//                        fk.add(u,v,f[i][2]);
//                        fk.add(v,u,f[i][2]);
//                }
//
//            for(int i=0;i<q;++i){
//                int u =  f1[i][0];
//                int v =  f1[i][1];
//
//
//
//
//                fk.add(u,v,f1[i][2]);
//            }




//                int dp[] = new int[n+1];
//                Arrays.fill(dp,100000000);
//                dp[s] = 0;
//
//
//                PriorityQueue<int[]> qu = new PriorityQueue<>(Comparator.comparingInt((x)->x[0]));
//                qu.add(new int[]{0,s});
//                while(qu.size()>0){
//                    int cc[] = qu.poll();
//                    int cur =  cc[1];
//                    if(cc[0]!=dp[cur]) continue;
//                    for(int j = h[cur];j!=-1;j=ne[j]){
//                        int v = to[j];
//                        if(dp[v] > dp[cur] + wt[j]){
//                            dp[v] = dp[cur] + wt[j];
//                            qu.offer(new int[]{dp[v],v});
//                        }
//                    }
//                }
//
//                for(int j=1;j<=n;++j){
//                    if(dp[j]==100000000){
//                        out.println("NO PATH");
//                    }else{
//                        out.println(dp[j]);
//                    }
//                }



//                for(int t=0;t<5;++t) {
//                    int at = fi[t];
//                    dp[at][t] = 0;
//                    PriorityQueue<int[]> q = new PriorityQueue<>(Comparator.comparingInt((x) -> x[0]));
//                    q.offer(new int[]{0, at});
//                    while (q.size() > 0) {
//                        int cur[] = q.poll();
//                        if (cur[0] != dp[cur[1]][t]) continue;
//                        int i = cur[1];
//                        for (int j = h[i]; j != -1; j = ne[j]) {
//                            int v = to[j];
//                            if (dp[i][t] + wt[j] < dp[v][t]) {
//                                dp[v][t] = dp[i][t] + wt[j];
//                                q.offer(new int[]{dp[v][t], v});
//                            }
//                        }
//                    }
//                }
//                int cl[] = new int[]{0,1,2,3,4};
//                int rs = Integer.MAX_VALUE;
//                do{
//                    int s= dp[1][cl[0]];
//                    for(int j=0;j<4;++j){
//                        int nxt = fi[cl[j+1]];
//                        s += dp[nxt][cl[j]];
//                    }
//                    rs = Math.min(rs,s);
//
//
//                }while(next_perm(cl));
//
//                out.print(rs);










    boolean next_perm(int[] a){
        int len = a.length;
        for(int i=len-2,j = 0;i>=0;--i){
            if(a[i]<a[i+1]){
                j = len-1;
                for(;a[j]<=a[i];--j);
                int p = a[j];
                a[j] = a[i];
                a[i] = p;
                j = i+1;
                for(int ed = len-1;j<ed;--ed) {
                    p = a[ed];
                    a[ed] = a[j];
                    a[j++] = p;
                }
                return true;
            }
        }
        return false;
    }


    static long mul(long a, long b, long p) {
        long res = 0, base = a;

        while (b > 0) {
            if ((b & 1L) > 0)
                res = (res + base) % p;

            base = (base + base) % p;
            b >>= 1;
        }

        return res;
    }

    static long mod_pow(long k, long n, long p) {
        long res = 1L;
        long temp = k % p;

        while (n != 0L) {
            if ((n & 1L) == 1L) {
                res = mul(res, temp, p);
            }

            temp = mul(temp, temp, p);
            n = n >> 1L;
        }

        return res % p;
    }


    public static double roundD(double result, int scale) {
        BigDecimal bg = new BigDecimal(result).setScale(scale, RoundingMode.UP);
        return bg.doubleValue();
    }



}
    private static void solve() {
        InputStream inputStream = System.in;
//                InputStream inputStream  = null;
//                try {
//                    inputStream = new FileInputStream(new File("D:\\chrome_download\\exp.out"));
//                } catch (FileNotFoundException e) {
//                    e.printStackTrace();
//                }
        OutputStream outputStream = System.out;
//                OutputStream outputStream = null;
//                File f = new File("D:\\chrome_download\\");
//                try {
//                    f.createNewFile();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//                try {
//                    outputStream = new FileOutputStream(f);
//                } catch (FileNotFoundException e) {
//                    e.printStackTrace();
//                }
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task task = new Task();
        task.solve(1, in, out);
        out.close();
    }
    public static void main(String[] args) {
        new Thread(null, () -> solve(), "1", (1 << 30)).start();
        // solve();
    }
static class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;
    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }
    public String nextLine() {
        String line = null;

        try {
            line = reader.readLine();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return line;
    }
    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        return tokenizer.nextToken();
    }
    public int nextInt() {
        return Integer.parseInt(next());
    }
    public char nextChar() {
        return next().charAt(0);
    }
    public int[] nextArray(int n) {
        int res[] = new int[n];

        for (int i = 0; i < n; ++i) {
            res[i] = nextInt();
        }

        return res;
    }
    public long nextLong() {
        return Long.parseLong(next());
    }
    public double nextDouble() {
        return Double.parseDouble(next());
    }
}
}

C++11(clang++ 3.9) 解法, 执行用时: 29ms, 内存消耗: 2008K, 提交时间: 2020-05-30 10:45:53

#include<bits/stdc++.h>
using namespace std;
const int MAXN=12e4;
int deg[MAXN];
int cnt1[MAXN];
int cnt2[MAXN];
int p[MAXN];
int find(int x)
{
	return p[x]=p[x]==x?x:find(p[x]);
}
int main()
{
	for(int i=0;i<MAXN;i++)
	p[i]=i;
	int n,m;
	cin>>n>>m;
	int cnt0=0;
	while(m--)
	{
		int u,v;
		cin>>u>>v;
		if(u==0) u=++n,cnt0++;
		if(v==0) v=++n,cnt0++;
		deg[u]++,deg[v]++;
		int pu=find(u),pv=find(v);
		if(pu!=pv) p[pu]=pv;
	}
	for(int i=0;i<=n;i++)
	{
		if(deg[i]>2) cnt1[find(i)]++;
		if(deg[i]%2) cnt2[find(i)]++;
	}
	int tot=0;
	int cnt=0;
	int tmpAns=0;
	for(int i=1;i<=n;i++)
	if(find(i)==i&&deg[i])
	{
		cnt++;
		if(cnt2[i]==0) tot+=max(cnt1[i],1)+1;
		else tot+=cnt1[i]+cnt2[i]/2;
		tmpAns=cnt1[i]+cnt2[i]/2; 
	}
	if(cnt==1) cout<<tmpAns<<endl;
	else cout<<tot<<endl;
}

上一题