Problem:
Network Reliability
An undirected graph is given.
Each edge of the graph disappears with a constant probability.
Calculate the probability with which the remained graph is connected.
Input
The first line contains three integers
N
(
1 \leq N \leq 14
),
M
(
0 \leq M \leq 100
) and
P
(
0 \leq P \leq 100
), separated by a single space.
N
is the number of the vertices and
M
is the number of the edges.
P
is the probability represented by a percentage.
The following
M
lines describe the edges.
Each line contains two integers
v_i
and
u_i
(
1 \leq u_i, v_i \leq N
).
(
u_i, v_i
) indicates the edge that connects the two vertices
u_i
and
v_i
.
Output
Output a line containing the probability with which the remained graph is connected.
Your program may output an arbitrary number of digits after the decimal point. However, the absolute error should be
10^{-9}
or less.
Sample Input 1
3 3 50
1 2
2 3
3 1
Output for the Sample Input 1
0.500000000000
Sample Input 2
3 3 10
1 2
2 3
3 1
Output for the Sample Input 2
0.972000000000
Sample Input 3
4 5 50
1 2
2 3
3 4
4 1
1 3
Output for the Sample Input 3
0.437500000000

Submitted solutions:

code_snippet: /*
 * 2345.cc: Network Reliability
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_N = 14;
const int NBITS = 1 << MAX_N;

/* typedef */

typedef pair<int,int> pii;

/* global variables */

pii es[MAX_N];
double dp[NBITS];

/* subroutines */

/* main */

int main() {
  int n, m;
  double p;
  cin >> n >> m >> p;

  int nbits = 1 << n;
  p /= 100;
  memset(es, false, sizeof(es));

  for (int i = 0; i < m; i++) {
    cin >> es[i].first >> es[i].second;
    es[i].first--, es[i].second--;
  }

  for (int bits = 0; bits < nbits; bits++) dp[bits] = 0.0;
  
  for (int bits = 1; bits < nbits; bits++) {
    int b0 = 1;
    for (; ! (bits & b0); b0 <<= 1);
    dp[bits] = 1.0;
    
    for (int s0 = (bits - 1) & bits; s0 != 0; s0 = (s0 - 1) & bits)
      if (s0 & b0) {
	int s1 = bits & ~s0;
	double pp = dp[s0];
	for (int j = 0; j < m; j++) {
	  int &u = es[j].first, &v = es[j].second;
	  int bu = 1 << u, bv = 1 << v;
	  if ((bits & bu) && (bits & bv) &&
	      (((s0 & bu) && ! (s0 & bv)) || ((! (s0 & bu) && (s0 & bv)))))
	    pp *= p;
	}
	dp[bits] -= pp;
      }
  }

  printf("%.12lf\n", dp[nbits - 1]);
  return 0;
}
accuracy: 1
time_ms: 850
memory_kb: 3692
final_rank: 12

code_snippet: // competitive-verifier: PROBLEM
#ifdef ATCODER
#pragma GCC target("sse4.2,avx512f,avx512dq,avx512ifma,avx512cd,avx512bw,avx512vl,bmi2")
#endif
#pragma GCC optimize("Ofast,fast-math,unroll-all-loops")
#include <bits/stdc++.h>
#ifndef ATCODER
#pragma GCC target("sse4.2,avx2,bmi2")
#endif
template <class T, class U>
constexpr bool chmax(T &a, const U &b) {
    return a < (T)b ? a = (T)b, true : false;
}
template <class T, class U>
constexpr bool chmin(T &a, const U &b) {
    return (T)b < a ? a = (T)b, true : false;
}
constexpr std::int64_t INF = 1000000000000000003;
constexpr int Inf = 1000000003;
constexpr double EPS = 1e-7;
constexpr double PI = 3.14159265358979323846;
#define FOR(i, m, n) for (int i = (m); i < int(n); ++i)
#define FORR(i, m, n) for (int i = (m)-1; i >= int(n); --i)
#define FORL(i, m, n) for (int64_t i = (m); i < int64_t(n); ++i)
#define rep(i, n) FOR (i, 0, n)
#define repn(i, n) FOR (i, 1, n + 1)
#define repr(i, n) FORR (i, n, 0)
#define repnr(i, n) FORR (i, n + 1, 1)
#define all(s) (s).begin(), (s).end()
struct Sonic {
    Sonic() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(20);
    }
    constexpr void operator()() const {}
} sonic;
using namespace std;
using ll = std::int64_t;
using ld = long double;
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
    return is >> p.first >> p.second;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
    for (T &i : v) is >> i;
    return is;
}
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
    return os << '(' << p.first << ',' << p.second << ')';
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
    for (auto it = v.begin(); it != v.end(); ++it) os << (it == v.begin() ? "" : " ") << *it;
    return os;
}
template <class Head, class... Tail>
void co(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cout << head << '\n';
    else std::cout << head << ' ', co(std::forward<Tail>(tail)...);
}
template <class Head, class... Tail>
void ce(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cerr << head << '\n';
    else std::cerr << head << ' ', ce(std::forward<Tail>(tail)...);
}
void Yes(bool is_correct = true) { std::cout << (is_correct ? "Yes\n" : "No\n"); }
void No(bool is_not_correct = true) { Yes(!is_not_correct); }
void YES(bool is_correct = true) { std::cout << (is_correct ? "YES\n" : "NO\n"); }
void NO(bool is_not_correct = true) { YES(!is_not_correct); }
void Takahashi(bool is_correct = true) { std::cout << (is_correct ? "Takahashi" : "Aoki") << '\n'; }
void Aoki(bool is_not_correct = true) { Takahashi(!is_not_correct); }
int main(void) {
    int n, m, p;
    cin >> n >> m >> p;
    vector g(n, 0);
    rep (i, m) {
        int x, y;
        cin >> x >> y;
        --x, --y;
        g[x] |= 1 << y;
        g[y] |= 1 << x;
    }
    vector<double> v(m + 1);
    v[0] = 1;
    rep (i, m) v[i + 1] = v[i] * p / 100;
    vector<double> dp(1 << n, 1);
    rep (bit, 1 << n) {
        if (bit == 0) {
            dp[0] = 1;
            continue;
        }
        int x = 0;
        rep (i, n) {
            if (bit >> i & 1) {
                x = i;
                break;
            }
        }
        for (int k = bit & (bit - 1); k > 0; k = bit & (k - 1)) {
            if (~k >> x & 1)
                continue;
            int c = 0;
            int l = bit ^ k;
            rep (i, n) {
                if (k >> i & 1)
                    c += popcount((unsigned)(l & g[i]));
            }
            dp[bit] -= dp[k] * v[c];
        }
    }
    co(dp.back());
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3968
final_rank: 6

code_snippet: // competitive-verifier: PROBLEM
#ifdef ATCODER
#pragma GCC target("sse4.2,avx512f,avx512dq,avx512ifma,avx512cd,avx512bw,avx512vl,bmi2")
#endif
#pragma GCC optimize("Ofast,fast-math,unroll-all-loops")
#include <bits/stdc++.h>
#ifndef ATCODER
#pragma GCC target("sse4.2,avx2,bmi2")
#endif
template <class T, class U>
constexpr bool chmax(T &a, const U &b) {
    return a < (T)b ? a = (T)b, true : false;
}
template <class T, class U>
constexpr bool chmin(T &a, const U &b) {
    return (T)b < a ? a = (T)b, true : false;
}
constexpr std::int64_t INF = 1000000000000000003;
constexpr int Inf = 1000000003;
constexpr double EPS = 1e-7;
constexpr double PI = 3.14159265358979323846;
#define FOR(i, m, n) for (int i = (m); i < int(n); ++i)
#define FORR(i, m, n) for (int i = (m)-1; i >= int(n); --i)
#define FORL(i, m, n) for (int64_t i = (m); i < int64_t(n); ++i)
#define rep(i, n) FOR (i, 0, n)
#define repn(i, n) FOR (i, 1, n + 1)
#define repr(i, n) FORR (i, n, 0)
#define repnr(i, n) FORR (i, n + 1, 1)
#define all(s) (s).begin(), (s).end()
struct Sonic {
    Sonic() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(20);
    }
    constexpr void operator()() const {}
} sonic;
using namespace std;
using ll = std::int64_t;
using ld = long double;
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
    return is >> p.first >> p.second;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
    for (T &i : v) is >> i;
    return is;
}
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
    return os << '(' << p.first << ',' << p.second << ')';
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
    for (auto it = v.begin(); it != v.end(); ++it) os << (it == v.begin() ? "" : " ") << *it;
    return os;
}
template <class Head, class... Tail>
void co(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cout << head << '\n';
    else std::cout << head << ' ', co(std::forward<Tail>(tail)...);
}
template <class Head, class... Tail>
void ce(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cerr << head << '\n';
    else std::cerr << head << ' ', ce(std::forward<Tail>(tail)...);
}
void Yes(bool is_correct = true) { std::cout << (is_correct ? "Yes\n" : "No\n"); }
void No(bool is_not_correct = true) { Yes(!is_not_correct); }
void YES(bool is_correct = true) { std::cout << (is_correct ? "YES\n" : "NO\n"); }
void NO(bool is_not_correct = true) { YES(!is_not_correct); }
void Takahashi(bool is_correct = true) { std::cout << (is_correct ? "Takahashi" : "Aoki") << '\n'; }
void Aoki(bool is_not_correct = true) { Takahashi(!is_not_correct); }
int main(void) {
    int n, m, p;
    cin >> n >> m >> p;
    vector<pair<int, int>> e(m);
    rep (i, m) {
        int x, y;
        cin >> x >> y;
        e[i] = {x - 1, y - 1};
    }
    vector<double> v(m + 1);
    v[0] = 1;
    rep (i, m) v[i + 1] = v[i] * p / 100;
    vector<double> dp(1 << n, 1);
    rep (bit, 1 << n) {
        if (bit == 0) {
            dp[0] = 1;
            continue;
        }
        int x = 0;
        rep (i, n) {
            if (bit >> i & 1) {
                x = i;
                break;
            }
        }
        for (int k = bit & (bit - 1); k > 0; k = bit & (k - 1)) {
            if (~k >> x & 1)
                continue;
            int c = 0;
            int l = bit ^ k;
            rep (i, m) {
                if ((k >> e[i].first & 1) && (l >> e[i].second & 1))
                    ++c;
                if ((l >> e[i].first & 1) && (k >> e[i].second & 1))
                    ++c;
            }
            dp[bit] -= dp[k] * v[c];
        }
    }
    co(dp.back());
    return 0;
}
accuracy: 1
time_ms: 510
memory_kb: 3968
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;

int main(){
	int N,M; cin >> N >> M;
	double P; cin >> P;
	P /= 100;
	vector<int> A(M) , B(M);
	for(int i = 0; i < M; i++){
		cin >> A[i] >> B[i];
		--A[i]; --B[i];
	}
	vector<double> dp(1<<N);
	for(int S = 1; S < (1<<N); S++){
		int v = 0;
		for(int i = 0; i < N; i++)if(S >> i & 1)v = i;
		dp[S] = 1;
		for(int T = (S-1)&S; T > 0; T = (T-1)&S){
			if(!(T >> v & 1))continue;
			double tmp = dp[T];
			for(int i = 0; i < M; i++){
				if((!(S >> A[i] & 1)) || (!(S >> B[i] & 1)))continue;
				if((T >> A[i] & 1) && (!(T >> B[i] & 1))){
					tmp *= P;
				}
				if((!(T >> A[i] & 1)) && (T >> B[i] & 1)){
					tmp *= P;
				}
			}
			dp[S] -= tmp;
		}
	}
	cout << fixed << setprecision(20) << dp[(1<<N)-1] << endl;
}
accuracy: 1
time_ms: 930
memory_kb: 3568
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;

#pragma GCC target("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")

#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")


using ll = long long;
using ld = long double;

ld dp[1<<15];

int main() {
  int N, M; cin >> N >> M;
  ld P; cin >> P;
  P = 100 - P;
  P /= 100;
  
  vector< array<int, 2> > edge(M);
  for (int i = 0; i < M; ++i) {
    int u, v; cin >> u >> v;
    u--, v--;
    edge[i] = {u, v};
  }
  
  vector< vector<int> > con(1<<N, vector<int>(N, 0));
  for (int bit = 1; bit < (1<<N); ++bit) {
    if (!(bit & 1)) continue;
    for (int j = 0; j < N; ++j) {
      if (bit & (1<<j)) con[bit][j] = 1;
    }
  }
  
  for (int bit = 1; bit < (1<<N); ++bit) {
    if (!(bit & 1)) continue;
    if (bit == 1) {
      dp[bit] = 1.0;
      continue;
    }
    
    ld res = 1.0;
    for (int sub = bit; sub > 0; sub = (sub - 1) & bit) {
      if (sub == bit) continue;
      if (!(sub & 1)) continue;
      
      int num = 0;
      for (auto [u, v] : edge) {
        if (con[bit][u] && con[bit][v]) {
          if (con[sub][u] != con[sub][v]) {
            num++;
          }
        }
      }
      ld add = dp[sub] * pow(1 - P, num);
      res -= add;
    }
    dp[bit] = res;
  }
  
  int full = (1<<N) - 1;
  cout << fixed << setprecision(20);
  cout << dp[full] << endl;
  
  return 0;
}
accuracy: 1
time_ms: 1300
memory_kb: 5248
final_rank: 16

code_snippet: //#pragma once
//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#include <bits/stdc++.h>
using namespace std;

#define REP(i,a,b) for (int i = a; i < (b); i++)
#define rep(i,a,b) for (int i = a; i < (b); i++)
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<long long> vl;
typedef set<int> si;
typedef set<long long> sl;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const ll MOD = 1e9+7;
const double pi = acos(-1);
const int N = 14;

ll adj[1 << N];
ld f[1 << N];
ld g[1 << N];
ld pots[110];

void solve_test_case(){
    ld p;
    ll n, m; cin >> n >> m >> p;
    p /= (ld) 100;
    pots[0] = 1;
    rep(i,1,110) pots[i] = pots[i - 1] * p;
    rep(i,0,m){
        int a, b; cin >> a >> b;
        a--,b--;
        adj[a] |= (1 << b);
        adj[b] |= (1 << a);
    }

    rep(i,1, 1 << n){
        f[i] = 1;
        for(int sub = (i - 1) & i; sub > 0; sub = (sub - 1) & i){
            ll cnt = 0;
            rep(j,0,n){
                if(sub & (1 << j))
                    cnt += __builtin_popcount(adj[j] & (i ^ sub));             
            }

            if(sub & 1) f[i] -= f[sub] * pots[cnt];
        }

    }
    //rep(i, 1, 1 << n){
      //  cout << f[i] << " " << g[i] << "\n"; 
    //}
    cout << f[(1 << n) - 1] << "\n";
}


int main(){
    ios::sync_with_stdio(0);
    cout << setprecision(20) << fixed;
    cin.tie(0);
    cout.tie(0);
    int tc = 1;

    while(tc--) solve_test_case();

    return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 3868
final_rank: 8

code_snippet: /*
https://drken1215.hatenablog.com/entry/2021/08/12/182200
*/
#include<iostream>
#include<set>
#include<algorithm>
#include<vector>
#include<string>
#include<set>
#include<map>
#include<stack>
#include<numeric>
#include<queue>
#include<cmath>
#include<deque>
#include<cassert>
using namespace std;
typedef long long ll;
const ll INF=1LL<<60;
typedef pair<int,int> P;
typedef pair<int,P> PP;
const ll MOD=998244353;


int main(){
    int N,M;
    double p;
    cin>>N>>M>>p;//確率pで消える
    p/=100;

    vector<vector<int>> edge(N,vector<int>(N,0));
    vector<int> a(M),b(M);
    for(int i=0;i<M;i++){
        cin>>a[i]>>b[i];
        a[i]--;b[i]--;   
        edge[a[i]][b[i]]=1;
        edge[b[i]][a[i]]=1;
    }
    vector<int> e(1<<N,0);
    for(int S=0;S<(1<<N);S++){
        for(int i=0;i<M;i++){
            if((S>>a[i])&1 && (S>>b[i])&1){
                e[S]++;
            }
        }
    }

    vector<double> ppow(M+1,0);//ppow[i]=p^i
    ppow[0]=1;

    for(int i=1;i<=M;i++){
        ppow[i]=p*ppow[i-1];
    }

    const int V=(1<<N)-1;

    //S,Tは必ず0を含むとする
    vector<double> f(1<<N,0);

    for(int S=0;S<(1<<N);S++){
        
        f[S]=1;
        for(int T=S;T>=0;T--){
            T&=S;
            int sub=S-T;
            if(T==S) continue;

            if((T>>0)&1){//Tの中に0があることが条件　これはSの中に0があることも意味する
                f[S]-=f[T]*ppow[e[S]-e[T]-e[sub]];
            }

        }
    }

    printf("%.10f\n",f[V]);
    
    /*
    f[1<<0]=1;
    for(int S=0;S<(1<<N);S++){
        for(int i=0;i<N;i++){
            for(int j=0;j<N;j++){
                if(i==j) continue;
                if((S>>i)&1 && !((S>>j)&1) && edge[i][j]==1){
                    f[S|(1<<j)]+=f[S]*p;
                }
            }
        }
    }
    */


}
accuracy: 1
time_ms: 10
memory_kb: 3680
final_rank: 1

code_snippet: /*
https://drken1215.hatenablog.com/entry/2021/08/12/182200
*/
#include<iostream>
#include<set>
#include<algorithm>
#include<vector>
#include<string>
#include<set>
#include<map>
#include<stack>
#include<numeric>
#include<queue>
#include<cmath>
#include<deque>
#include<cassert>
using namespace std;
typedef long long ll;
const ll INF=1LL<<60;
typedef pair<int,int> P;
typedef pair<int,P> PP;
const ll MOD=998244353;


int main(){
    int N,M;
    double p;
    cin>>N>>M>>p;
    p/=100;

    vector<vector<int>> edge(N,vector<int>(N,0));
    vector<int> a(M),b(M);
    for(int i=0;i<M;i++){
        cin>>a[i]>>b[i];
        a[i]--;b[i]--;   
        edge[a[i]][b[i]]=1;
        edge[b[i]][a[i]]=1;
    }
    vector<int> e(1<<N,0);
    for(int S=0;S<(1<<N);S++){
        for(int i=0;i<M;i++){
            if((S>>a[i])&1 && (S>>b[i])&1){
                e[S]++;
            }
        }
    }

    vector<double> ppow(M+1,0);//ppow[i]=p^i
    ppow[0]=1;

    for(int i=1;i<=M;i++){
        ppow[i]=p*ppow[i-1];
    }

    const int V=(1<<N)-1;

    vector<double> f(1<<N,0);
    /*
    for(int i=0;i<N;i++){
        f[1<<i]=1;
    } 
    */
    for(int S=0;S<(1<<N);S++){
        
        f[S]=1;
        for(int T=S;T>=0;T--){
            T&=S;
            int sub=S-T;
            if(T==S) continue;

            if((T>>0)&1){
                f[S]-=f[T]*ppow[e[S]-e[T]-e[sub]];
            }

            /*

            double discon=1;//T,subがつながらない確率
            for(int i=0;i<N;i++){
                for(int j=0;j<N;j++){
                    if(i==j) continue;
                    if( ((T>>i)&1) && ((sub>>j)&1) && edge[i][j]==1 ){
                        discon*=(1-p);
                    }
                }
            }

            double con=1-discon;
            f[S]+=f[T]*f[sub]*con;
            */
        }
    }

    printf("%.10f\n",f[V]);
    
    /*
    f[1<<0]=1;
    for(int S=0;S<(1<<N);S++){
        for(int i=0;i<N;i++){
            for(int j=0;j<N;j++){
                if(i==j) continue;
                if((S>>i)&1 && !((S>>j)&1) && edge[i][j]==1){
                    f[S|(1<<j)]+=f[S]*p;
                }
            }
        }
    }
    */


}
accuracy: 1
time_ms: 10
memory_kb: 3752
final_rank: 4

code_snippet: /*
https://drken1215.hatenablog.com/entry/2021/08/12/182200
*/
#include<iostream>
#include<set>
#include<algorithm>
#include<vector>
#include<string>
#include<set>
#include<map>
#include<stack>
#include<numeric>
#include<queue>
#include<cmath>
#include<deque>
#include<cassert>
using namespace std;
typedef long long ll;
const ll INF=1LL<<60;
typedef pair<int,int> P;
typedef pair<int,P> PP;
const ll MOD=998244353;


int main(){
    int N,M;
    double p;
    cin>>N>>M>>p;
    p/=100;

    vector<vector<int>> edge(N,vector<int>(N,0));
    vector<int> a(M),b(M);
    for(int i=0;i<M;i++){
        cin>>a[i]>>b[i];
        a[i]--;b[i]--;   
        edge[a[i]][b[i]]=1;
        edge[b[i]][a[i]]=1;
    }
    vector<int> e(1<<N,0);
    for(int S=0;S<(1<<N);S++){
        for(int i=0;i<M;i++){
            if((S>>a[i])&1 && (S>>b[i])&1){
                e[S]++;
            }
        }
    }

    vector<double> ppow(M+1,0);//ppow[i]=p^i
    ppow[0]=1;

    for(int i=1;i<=M;i++){
        ppow[i]=p*ppow[i-1];
    }

    const int V=(1<<N)-1;

    vector<double> f(1<<N,0);
    for(int i=0;i<N;i++){
        f[1<<i]=1;
    } 
    for(int S=0;S<(1<<N);S++){
        
        f[S]=1;
        for(int T=S;T>=0;T--){
            T&=S;
            int sub=S-T;
            if(T==S) continue;

            if((T>>0)&1){
                f[S]-=f[T]*ppow[e[S]-e[T]-e[sub]];
            }

            /*

            double discon=1;//T,subがつながらない確率
            for(int i=0;i<N;i++){
                for(int j=0;j<N;j++){
                    if(i==j) continue;
                    if( ((T>>i)&1) && ((sub>>j)&1) && edge[i][j]==1 ){
                        discon*=(1-p);
                    }
                }
            }

            double con=1-discon;
            f[S]+=f[T]*f[sub]*con;
            */
        }
    }

    printf("%.10f\n",f[V]);
    
    /*
    f[1<<0]=1;
    for(int S=0;S<(1<<N);S++){
        for(int i=0;i<N;i++){
            for(int j=0;j<N;j++){
                if(i==j) continue;
                if((S>>i)&1 && !((S>>j)&1) && edge[i][j]==1){
                    f[S|(1<<j)]+=f[S]*p;
                }
            }
        }
    }
    */


}
accuracy: 1
time_ms: 10
memory_kb: 3720
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
#define REP(i,n) for(int i=0,_n=(int)(n);i<_n;++i)
#define ALL(v) (v).begin(),(v).end()
#define CLR(t,v) memset(t,(v),sizeof(t))
template<class T1,class T2>ostream& operator<<(ostream& os,const pair<T1,T2>&a){return os<<"("<<a.first<<","<<a.second<< ")";}
template<class T>void chmin(T&a,const T&b){if(a>b)a=b;}
template<class T>void chmax(T&a,const T&b){if(a<b)a=b;}
#ifdef LOCAL
template<class T>void pv(T a,T b){for(T i=a;i!=b;++i)cerr<<(*i)<<" ";cerr<<endl;}
#else
template<class T>void pv(T a,T b){}
#endif

ll nextLong() { ll x; cin >> x; return x;}

double f[1 << 14];

int main2() {
  int N = nextLong();
  int M = nextLong();
  double P = nextLong() / 100.0;

  vector<int> A, B;
  REP(i, M) {
    int a = nextLong() - 1;
    int b = nextLong() - 1;
    A.push_back(a);
    B.push_back(b);
  }
  REP(s, 1 << N) {
    if (s == 0) {
      f[s] = 1.0;
      continue;
    }
    double val = 1.0;
    int v = 0;
    while ((s >> v & 1) == 0) v++;
    for (int t = s; t != 0; t = (t - 1) & s) {
      if (t == s) continue;
      if ((t >> v & 1) == 0) continue;
      double a = 1.0;
      REP(i, M) {
        if ((s >> A[i] & 1) && (s >> B[i] & 1)) {
          if ((t >> A[i] & 1) ^ (t >> B[i] & 1)) a *= P;
        }
      }
      val -= f[t] * a;
    }

    f[s] = val;
  }
  double ans = f[(1 << N) - 1];
  printf("%.10f\n", ans);
  return 0;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

#ifdef LOCAL
  for (;!cin.eof();cin>>ws)
#endif
    main2();
  return 0;
}
accuracy: 1
time_ms: 590
memory_kb: 3636
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
int main(){
  ios::sync_with_stdio(false);
  int n,m; double p; cin>>n>>m>>p,p/=100;
  vector g(n,vector<int>(n));
  for(int i=1;i<=m;i++){
    int u,v; cin>>u>>v;
    g[--u][--v]++,g[v][u]++;
  }
  vector<double> f(1<<n);
  for(int b=0;b<1<<n;b++){
    int l=b&-b;
    if(f[b]=1;b==l)continue;
    for(int x=b;x;x=b&x-1){
      if(x==b||!(x&l))continue;
      int y=b^x,c=0;
      for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
          if(x>>i&1&&y>>j&1&&g[i][j])c++;
      f[b]-=f[x]*pow(p,c);
    }
  }
  cout<<fixed<<setprecision(12)<<f[(1<<n)-1]<<endl;
  return 0;
}
accuracy: 1
time_ms: 710
memory_kb: 4004
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define rep(i, n) for (int i = 0; i < (n); i++)
#define per(i, n) for (int i = (n)-1; i >= 0; i--)
#define rep2(i, l, r) for (int i = (l); i < (r); i++)
#define per2(i, l, r) for (int i = (r)-1; i >= (l); i--)

using ld = long double;

int main() {
    int N, M, P;
    cin >> N >> M >> P;

    ld p = P * 0.01;

    vector<ld> pw(M + 1, 1);
    rep(i, M) pw[i + 1] = pw[i] * p;

    vector<vector<int>> es(N, vector<int>(N, 0));
    rep(i, M) {
        int u, v;
        cin >> u >> v;
        u--, v--;
        es[u][v] = es[v][u] = 1;
    }

    vector<ld> dp(1 << N, 1);
    int V = (1 << N) - 1;

    rep2(S, 1, 1 << N) {
        int id = -1;
        per(i, N) {
            if ((S >> i & 1)) id = i;
        }
        if (id == -1) break;
        int R = V & ~S & ~((1 << id) - 1);

        // cout << S << ' ' << id << ' ' << R << ' ' << dp[S] << endl;

        vector<int> c(N, 0);
        rep(i, N) {
            if (!(S >> i & 1)) continue;
            rep(j, N) {
                c[j] += es[i][j]; //
            }
        }

        auto get = [&](int T) {
            int cnt = 0;
            rep(i, N) {
                if (T >> i & 1) cnt += c[i];
            }
            return pw[cnt];
        };

        for (int T = R; T > 0; T--, T &= R) {
            // cout << S << ' ' << (S | T | (1 << id)) << ' ' << get(T | (1 << id)) << endl;
            dp[S | T] -= dp[S] * get(T);
            if (T == 0) break;
        }
    }

    cout << fixed << setprecision(15) << dp.back() << endl;
}
accuracy: 1
time_ms: 70
memory_kb: 3580
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
	int N, M, P;
	cin >> N >> M >> P;
	vector<int> A(M), B(M);
	for (int i = 0; i < M; i++) {
		cin >> A[i] >> B[i];
		A[i] -= 1;
		B[i] -= 1;
	}
	vector<int> cnt(1 << N);
	for (int i = 0; i < M; i++) {
		cnt[(1 << A[i]) | (1 << B[i])] += 1;
	}
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < (1 << N); j++) {
			if ((j >> i) & 1) {
				cnt[j] += cnt[j ^ (1 << i)];
			}
		}
	}
	vector<__float128> pw(M + 1);
	pw[0] = 1.0L;
	for (int i = 0; i < M; i++) {
		pw[i + 1] = pw[i] * (P / 100.0L);
	}
	vector<vector<__float128> > dp(1 << N);
	dp[0] = { 1.0L };
	for (int i = 1; i < 1 << N; i++) {
		int c = __builtin_popcount(i);
		dp[i].resize(c + 1);
		for (int j = i; j != 0; j = (j - 1) & i) {
			int edges = cnt[i] - cnt[i ^ j] - cnt[j];
			for (int k = 0; k < dp[i ^ j].size(); k++) {
				dp[i][k + 1] += dp[i ^ j][k] * pw[edges];
			}
		}
	}
	__float128 answer = 0.0;
	__float128 mul = 1.0;
	for (int i = 1; i <= N; i++) {
		answer += dp[(1 << N) - 1][i] * (i % 2 == 1 ? +1 : -1) / i;
	}
	cout.precision(15);
	cout << fixed << (long double)(answer) << endl;
	return 0;
}
accuracy: 1
time_ms: 820
memory_kb: 6088
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
	int N, M, P;
	cin >> N >> M >> P;
	vector<int> A(M), B(M);
	for (int i = 0; i < M; i++) {
		cin >> A[i] >> B[i];
		A[i] -= 1;
		B[i] -= 1;
	}
	vector<int> cnt(1 << N);
	for (int i = 0; i < M; i++) {
		cnt[(1 << A[i]) | (1 << B[i])] += 1;
	}
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < (1 << N); j++) {
			if ((j >> i) & 1) {
				cnt[j] += cnt[j ^ (1 << i)];
			}
		}
	}
	vector<long double> pw(M + 1);
	pw[0] = 1.0L;
	for (int i = 0; i < M; i++) {
		pw[i + 1] = pw[i] * (P / 100.0L);
	}
	vector<vector<long double> > dp(1 << N);
	dp[0] = { 1.0L };
	for (int i = 1; i < 1 << N; i++) {
		int c = __builtin_popcount(i);
		dp[i].resize(c + 1);
		for (int j = i; j != 0; j = (j - 1) & i) {
			int edges = cnt[i] - cnt[i ^ j] - cnt[j];
			for (int k = 0; k < dp[i ^ j].size(); k++) {
				dp[i][k + 1] += dp[i ^ j][k] * pw[edges];
			}
		}
	}
	long double answer = 0.0;
	long double mul = 1.0;
	for (int i = 1; i <= N; i++) {
		answer += dp[(1 << N) - 1][i] * (i % 2 == 1 ? +1 : -1) / i;
	}
	cout.precision(15);
	cout << fixed << answer << endl;
	return 0;
}
accuracy: 0.5581395348837209
time_ms: 50
memory_kb: 6084
final_rank: 19

code_snippet: #include<bits/stdc++.h>
using namespace std;

void dbg_out() { cout << endl; }
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << H; dbg_out(T...); }

#ifdef LOCAL
#define debug(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
#define debug(...) "zzz"
#endif

using ll = long long;
using ld = long double;
using pii = pair<ll,ll>;

#define FOR(i, n) for(int i = 1; i<=n; i++)
#define F0R(i, n) for(int i = 0; i<n; i++)
#define all(x) x.begin(), x.end()
#define mp make_pair
#define pb push_back
#define f first
#define s second

template<typename T, typename = void> struct is_iterable : false_type {};
template<typename T> struct is_iterable<T, void_t<decltype(begin(declval<T>())),decltype(end(declval<T>()))>> : true_type {};
template<typename T> typename enable_if<is_iterable<T>::value&&!is_same<T, string>::value,ostream&>::type operator<<(ostream &cout, T const &v);
template<typename A, typename B> ostream& operator<<(ostream &cout, pair<A, B> const &p) { return cout << "(" << p.f << ", " << p.s << ")"; }
template<typename T> typename enable_if<is_iterable<T>::value&&!is_same<T, string>::value,ostream&>::type operator<<(ostream &cout, T const &v) {
	cout << "["; 
	for (auto it = v.begin(); it != v.end();) {
		cout << *it;
		if (++it != v.end()) cout << ", ";
	}
	return cout << "]";
}

//var 
ll T;

void solve() {
	ll n, m, p;
	cin >> n >> m >> p;

	ld prob = (ld)p / 100.0;

	vector<ld> pow_p(m + 1, 1);
	FOR (i, m) pow_p[i] = pow_p[i - 1] * prob;

	vector<pii> edges(m);
	for (auto& [x, y] : edges) {
		cin >> x >> y;
		x--, y--;
	}	

	vector<ll> edge_count(1 << n);
	F0R (msk, (1 << n)) {
		for (auto [x, y] : edges) {
			if ((msk >> x) & 1) if ((msk >> y) & 1) {
				edge_count[msk]++;	
			}
		}
	}

	// probability sub mask forms connected component of node = 1
	vector<ld> dp(1 << n);
	F0R (msk, (1 << n)) if (msk & 1) {
		dp[msk] = 1;
		for (ll sub_mask = msk; sub_mask > 0; sub_mask = (sub_mask - 1) & msk) {
			if (sub_mask == msk) continue;
			if (!(sub_mask & 1)) continue;

			ll edges_between = edge_count[msk] - edge_count[sub_mask] - edge_count[msk ^ sub_mask]; 
			dp[msk] -= pow_p[edges_between] * dp[sub_mask];
		}	
	}

	cout << fixed << setprecision(10);
	ll big = (1 << n) - 1;
	cout << dp[big] << "\n";
}

int main() {
	ios_base::sync_with_stdio(0); 
	cin.tie(0);

	T = 1;
	//cin >> T;
	FOR(t, T)
		solve();

	cout.flush();
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3680
final_rank: 1

code_snippet: #include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
  
#define pbds tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>

using namespace std;

#define ll              long long
#define int				ll
#define pb              push_back
#define ppb             pop_back
#define pf              push_front
#define ppf             pop_front
#define all(x)          (x).begin(), (x).end()
#define uniq(v)         (v).erase(unique(all(v)), (v).end())
#define sz(x)           (int)((x).size())
#define fr              first
#define sc              second
#define vi              vector<int>
#define vvi				vector<vi>
#define pii             pair<int, int>
#define rep(i,a,b)      for(int i = a; i < b; i++)
#define irep(i, a, b)   for(int i = a; i > b; i--)
#define mem1(a)         memset(a, -1, sizeof(a))
#define mem0(a)         memset(a, 0, sizeof(a))
#define clz             __builtin_clzll			//leading zeroes
#define ctz             __builtin_ctzll			//trailing zeroes
#define ppc             __builtin_popcountll
#define nl				cout << '\n'

template<typename T>
istream &operator>>(istream &in, vector<T>& v){
    for(int i = 0; i < v.size(); i++)
        in >> v[i];
    return in;
}
template<typename T>
ostream &operator<<(ostream &out, vector<T>& v){
    for(int i = 0; i < v.size(); i++)
        out << v[i] << " ";
    return out;
}
template<typename T1, typename T2>istream& operator>>(istream& in, pair<T1, T2>& p){ in >> p.fr >> p.sc; return in; }
template<typename T1, typename T2>ostream& operator<<(ostream& out, pair<T1, T2>& p){ out << p.fr << " " << p.sc << " "; return out; }

const ll INF = 1e18;
const int32_t M = 1e9 + 7;
const int32_t MM = 998244353;
const int MAX = numeric_limits<int>::max();
const int MIN = numeric_limits<int>::min();

const int N = 0;

int egcd(int a, int b, int& x, int& y, int mod){
	if(b == 0){
		x = 1, y = 0;
		return a;
	}
	int x1, y1, g = egcd(b, a % b, x1, y1, mod);
	x = y1 % mod, y = ((x1 - (a / b)*y1) % mod + mod) % mod;
	return g;
}

void solve(){
	int n, m; cin >> n >> m;
	double p; cin >> p; p /= 100.0;
	vector<pii> e;
	while(m--){
		int u, v; cin >> u >> v; u--; v--;
		e.pb({u, v});
	}
	vector<double> f(1<<n, 1.0), pw(400, 1);
	rep(i, 1, 400)	pw[i] = p * pw[i - 1];
	rep(msk, 1, 1<<n)	for(int x = msk; x; x = (x - 1)&msk)	if(x != msk && ctz(x) == ctz(msk)){
		int cnt = 0;
		for(auto [u, v] : e)	if(((x&(1<<u)) && ((msk^x)&(1<<v))) || ((x&(1<<v)) && ((msk^x)&(1<<u))))	cnt++;
		f[msk] -= pw[cnt] * f[x];
	}
	cout << setprecision(12) << fixed;
	cout << f[(1<<n) - 1]; nl;
}

signed main(){
	// #ifndef ONLINE_JUDGE
	// 	freopen("input.txt", "r", stdin);
	// 	freopen("output.txt", "w", stdout);
	// #endif
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	int t = 1; //cin >> t;
	rep(i, 0, t){
		solve();
	}
}
accuracy: 1
time_ms: 1050
memory_kb: 3664
final_rank: 14

code_snippet: #include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
  
#define pbds tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>

using namespace std;

#define ll              long long
#define int				ll
#define pb              push_back
#define ppb             pop_back
#define pf              push_front
#define ppf             pop_front
#define all(x)          (x).begin(), (x).end()
#define uniq(v)         (v).erase(unique(all(v)), (v).end())
#define sz(x)           (int)((x).size())
#define fr              first
#define sc              second
#define vi              vector<int>
#define vvi				vector<vi>
#define pii             pair<int, int>
#define rep(i,a,b)      for(int i = a; i < b; i++)
#define irep(i, a, b)   for(int i = a; i > b; i--)
#define mem1(a)         memset(a, -1, sizeof(a))
#define mem0(a)         memset(a, 0, sizeof(a))
#define clz             __builtin_clzll			//leading zeroes
#define ctz             __builtin_ctzll			//trailing zeroes
#define ppc             __builtin_popcountll
#define nl				cout << '\n'

template<typename T>
istream &operator>>(istream &in, vector<T>& v){
    for(int i = 0; i < v.size(); i++)
        in >> v[i];
    return in;
}
template<typename T>
ostream &operator<<(ostream &out, vector<T>& v){
    for(int i = 0; i < v.size(); i++)
        out << v[i] << " ";
    return out;
}
template<typename T1, typename T2>istream& operator>>(istream& in, pair<T1, T2>& p){ in >> p.fr >> p.sc; return in; }
template<typename T1, typename T2>ostream& operator<<(ostream& out, pair<T1, T2>& p){ out << p.fr << " " << p.sc << " "; return out; }

const ll INF = 1e18;
const int32_t M = 1e9 + 7;
const int32_t MM = 998244353;
const int MAX = numeric_limits<int>::max();
const int MIN = numeric_limits<int>::min();

const int N = 0;

int egcd(int a, int b, int& x, int& y, int mod){
	if(b == 0){
		x = 1, y = 0;
		return a;
	}
	int x1, y1, g = egcd(b, a % b, x1, y1, mod);
	x = y1 % mod, y = ((x1 - (a / b)*y1) % mod + mod) % mod;
	return g;
}

void solve(){
	int n, m; cin >> n >> m;
	double p; cin >> p; p /= 100.0;
	vector<pii> e;
	while(m--){
		int u, v; cin >> u >> v; u--; v--;
		e.pb({u, v});
	}
	vector<double> f(1<<n, 1.0), pw(400, 1);
	rep(i, 1, 400)	pw[i] = p * pw[i - 1];
	rep(msk, 1, 1<<n)	for(int x = msk; x; x = (x - 1)&msk)	if(x != msk && ctz(x) == ctz(msk)){
		int cnt = 0;
		for(auto [u, v] : e)	if(((x&(1<<u)) && ((msk^x)&(1<<v))) || ((x&(1<<v)) && ((msk^x)&(1<<u))))	cnt++;
		f[msk] -= pw[cnt] * f[x];
	}
	cout << setprecision(12);
	cout << f[(1<<n) - 1]; nl;
}

signed main(){
	// #ifndef ONLINE_JUDGE
	// 	freopen("input.txt", "r", stdin);
	// 	freopen("output.txt", "w", stdout);
	// #endif
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	int t = 1; //cin >> t;
	rep(i, 0, t){
		solve();
	}
}
accuracy: 0.08139534883720931
time_ms: 10
memory_kb: 3552
final_rank: 20

code_snippet: #line 1 "library/Template/template.hpp"
#include <bits/stdc++.h>
using namespace std;

#define rep(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define ALL(v) (v).begin(),(v).end()
using ll=long long int;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;
template<typename T>inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<typename T>inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
#line 2 "library/Utility/fastio.hpp"
#include <unistd.h>

class FastIO{
    static constexpr int L=1<<16;
    char rdbuf[L];
    int rdLeft=0,rdRight=0;
    inline void reload(){
        int len=rdRight-rdLeft;
        memmove(rdbuf,rdbuf+rdLeft,len);
        rdLeft=0,rdRight=len;
        rdRight+=fread(rdbuf+len,1,L-len,stdin);
    }
    inline bool skip(){
        for(;;){
            while(rdLeft!=rdRight and rdbuf[rdLeft]<=' ')rdLeft++;
            if(rdLeft==rdRight){
                reload();
                if(rdLeft==rdRight)return false;
            }
            else break;
        }
        return true;
    }
    template<typename T,enable_if_t<is_integral<T>::value,int> =0>inline bool _read(T& x){
        if(!skip())return false;
        if(rdLeft+20>=rdRight)reload();
        bool neg=false;
        if(rdbuf[rdLeft]=='-'){
            neg=true;
            rdLeft++;
        }
        x=0;
        while(rdbuf[rdLeft]>='0' and rdLeft<rdRight){
            x=x*10+(neg?-(rdbuf[rdLeft++]^48):(rdbuf[rdLeft++]^48));
        }
        return true;
    }
    template<typename T,enable_if_t<is_floating_point<T>::value,int> =0>inline bool _read(T& x){
        if(!skip())return false;
        if(rdLeft+20>=rdRight)reload();
        bool neg=false;
        if(rdbuf[rdLeft]=='-'){
            neg=true;
            rdLeft++;
        }
        x=0;
        while(rdbuf[rdLeft]>='0' and rdbuf[rdLeft]<='9' and rdLeft<rdRight){
            x=x*10+(rdbuf[rdLeft++]^48);
        }
        if(rdbuf[rdLeft]!='.')return true;
        rdLeft++;
        T base=.1;
        while(rdbuf[rdLeft]>='0' and rdbuf[rdLeft]<='9' and rdLeft<rdRight){
            x+=base*(rdbuf[rdLeft++]^48);
            base*=.1;
        }
        if(neg)x=-x;
        return true;
    }
    inline bool _read(char& x){
        if(!skip())return false;
        if(rdLeft+1>=rdRight)reload();
        x=rdbuf[rdLeft++];
        return true;
    }
    inline bool _read(string& x){
        if(!skip())return false;
        for(;;){
            int pos=rdLeft;
            while(pos<rdRight and rdbuf[pos]>' ')pos++;
            x.append(rdbuf+rdLeft,pos-rdLeft);
            if(rdLeft==pos)break;
            rdLeft=pos;
            if(rdLeft==rdRight)reload();
            else break;
        }
        return true;
    }
    template<typename T>inline bool _read(vector<T>& v){
        for(auto& x:v){
            if(!_read(x))return false;
        }
        return true;
    }

    char wtbuf[L],tmp[50];
    int wtRight=0;
    inline void flush(){
        fwrite(wtbuf,1,wtRight,stdout);
        wtRight=0;
    }
    inline void _write(const char& x){
        if(wtRight>L-32)flush();
        wtbuf[wtRight++]=x;
    }
    inline void _write(const string& x){
        for(auto& c:x)_write(c);
    }
    template<typename T,enable_if_t<is_integral<T>::value,int> =0>inline void _write(T x){
        if(wtRight>L-32)flush();
        if(x==0){
            _write('0');
            return;
        }
        else if(x<0){
            _write('-');
            if (__builtin_expect(x == std::numeric_limits<T>::min(), 0)) {
                switch (sizeof(x)) {
                case 2: _write("32768"); return;
                case 4: _write("2147483648"); return;
                case 8: _write("9223372036854775808"); return;
                }
            }
            x=-x;
        }
        int pos=0;
        while(x!=0){
            tmp[pos++]=char((x%10)|48);
            x/=10;
        }
        rep(i,0,pos)wtbuf[wtRight+i]=tmp[pos-1-i];
        wtRight+=pos;
    }
    template<typename T>inline void _write(const vector<T>& v){
        rep(i,0,v.size()){
            if(i)_write(' ');
            _write(v[i]);
        }
    }
public:
    FastIO(){}
    ~FastIO(){flush();}
    inline void read(){}
    template <typename Head, typename... Tail>inline void read(Head& head,Tail&... tail){
        assert(_read(head));
        read(tail...); 
    }
    template<bool ln=true,bool space=false>inline void write(){if(ln)_write('\n');}
    template <bool ln=true,bool space=false,typename Head, typename... Tail>inline void write(const Head& head,const Tail&... tail){
        if(space)_write(' ');
        _write(head);
        write<ln,true>(tail...); 
    }
};

/**
 * @brief Fast IO
 */
#line 3 "sol.cpp"

#line 2 "library/Convolution/bitwise.hpp"

template<typename T>void zeta(vector<T>& a){
    int n=__lg(a.size());
    rep(k,0,n)rep(mask,0,1<<n){
        if(mask>>k&1)a[mask]+=a[mask^(1<<k)];
    }
}
template<typename T>void mobius(vector<T>& a){
    int n=__lg(a.size());
    rep(k,0,n)rep(mask,0,1<<n){
        if(mask>>k&1)a[mask]-=a[mask^(1<<k)];
    }
}
template<typename T>void fwt(vector<T>& a){
    int n=__lg(a.size());
    rep(k,0,n)rep(mask,0,1<<n){
        if(!(mask>>k&1)){
            T x=a[mask],y=a[mask|(1<<k)];
            a[mask]=x+y,a[mask|(1<<k)]=x-y;
        }
    }
}

/**
 * @brief Bitwise Convolution
 * @docs docs/bitwise.md
 */
#line 2 "library/Convolution/subset.hpp"

template<typename T>struct SubsetConvolution{
    const int LG;
    vector<int> bpc;
    vector<T> inv;
    SubsetConvolution(int lg=20):LG(lg),bpc(1<<LG),inv(LG+1){
        rep(i,1,1<<LG)bpc[i]=bpc[i-(i&-i)]+1;
        rep(i,1,LG+1)inv[i]=T(1)/i;
    }
    void zeta(vector<vector<T>>& a){
        int n=a.size();
        for(int w=1;w<n;w<<=1){
            for(int k=0;k<n;k+=w*2)rep(i,0,w){
                rep(j,0,bpc[k+w+i])a[k+w+i][j]+=a[k+i][j];
            }
        }
    }
    void mobius(vector<vector<T>>& a){
        int n=a.size(),m=__lg(n);
        for(int w=n>>1;w;w>>=1){
            for(int k=0;k<n;k+=w*2)rep(i,0,w){
                rep(j,bpc[k+w+i],m+1)a[k+w+i][j]-=a[k+i][j];
            }
        }
    }
    vector<T> mult(vector<T>& a,vector<T>& b,bool same=0){
        assert(a.size()==b.size());
        int n=a.size(),m=__lg(n);
        vector A(n,vector<T>(m+1)),B(n,vector<T>(m+1));
        rep(i,0,n){
            A[i][bpc[i]]=a[i];
            B[i][bpc[i]]=b[i];
        }
        zeta(A);
        if(same)B=A;
        else zeta(B);
        rep(i,0,n){
            vector<T> c(m+1);
            rep(j,0,m+1)rep(k,0,m+1-j)c[j+k]+=A[i][j]*B[i][k];
            swap(A[i],c);
        }
        mobius(A);
        vector<T> ret(n);
        rep(i,0,n)ret[i]=A[i][bpc[i]];
        return ret;
    }
    vector<T> exp(vector<T>& a){
        int n=a.size(),m=__lg(n);
        vector A(n,vector<T>(m+1));
        rep(i,0,n)A[i][bpc[i]]=a[i];
        zeta(A);
        rep(i,0,n){
            vector<T> ret(m+1);
            ret[0]=1;
            rep(j,1,m+1){
                rep(k,1,j+1)ret[j]+=ret[j-k]*A[i][k]*k;
                ret[j]*=inv[j];
            }
            swap(A[i],ret);
        }
        mobius(A);
        vector<T> ret(n);
        rep(i,0,n)ret[i]=A[i][bpc[i]];
        return ret;
    }
    vector<T> log(vector<T>& a){
        int n=a.size(),m=__lg(n);
        vector A(n,vector<T>(m+1));
        rep(i,0,n)A[i][bpc[i]]=a[i];
        zeta(A);
        rep(i,0,n){
            vector<T> ret(m+1);
            rep(j,1,m+1){
                ret[j]=A[i][j]*j;
                rep(k,1,j)ret[j]-=ret[k]*A[i][j-k]*k;
                ret[j]*=inv[j];
            }
            swap(A[i],ret);
        }
        mobius(A);
        vector<T> ret(n);
        rep(i,0,n)ret[i]=A[i][bpc[i]];
        return ret;
    }
    vector<T> sqrt(vector<T>& a){
        int n=a.size(),m=__lg(n);
        vector A(n,vector<T>(m+1));
        rep(i,0,n)A[i][bpc[i]]=a[i];
        zeta(A);
        rep(i,0,n){
            vector<T> ret(m+1);
            ret[0]=1;
            rep(j,1,m+1){
                ret[j]=A[i][j];
                rep(k,1,j)ret[j]-=ret[k]*ret[j-k];
                ret[j]*=inv[2];
            }
            swap(A[i],ret);
        }
        mobius(A);
        vector<T> ret(n);
        rep(i,0,n)ret[i]=A[i][bpc[i]];
        return ret;
    }
};

/**
 * @brief Subset Convolution
 */
#line 6 "sol.cpp"

FastIO io;
int main(){
    int n,m,p;
    io.read(n,m,p);
    if(p==0){
        io.write(1);
        return 0;
    }
    vector<int> es(1<<n);
    rep(_,0,m){
        int u,v;
        io.read(u,v);
        u--; v--;
        es[(1<<u)|(1<<v)]++;
    }
    zeta(es);
    using ld=long double;
    vector<ld> g(1<<n);
    rep(mask,0,1<<n)g[mask]=pow(ld(p)/100,-es[mask]);

    SubsetConvolution<ld> buf;
    auto f=buf.log(g);
    double ret=f[(1<<n)-1]*pow(ld(p)/100,es[(1<<n)-1]);
    printf("%.12f\n",ret);
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 12264
final_rank: 17

code_snippet: #include "bits/stdc++.h"
using namespace std;
using namespace std::chrono;
typedef long long int llint;
typedef long double lldo;
#define mp make_pair
#define mt make_tuple
#define pub push_back
#define puf push_front
#define pob pop_back
#define pof pop_front
#define fir first
#define sec second
#define res resize
#define ins insert
#define era erase
#define REP(i, n) for(int i = 0;i < (n);i++)
/*cout<<fixed<<setprecision(20);cin.tie(0);ios::sync_with_stdio(false);*/
const int mod=1000000007;
const llint inf=2.19e15+1;
const long double pai=3.141592653589793238462643383279502884197;
const long double eps=1e-10;
template <class T,class U>bool chmin(T& a,U b){if(a>b){a=b;return true;}return false;}
template <class T,class U>bool chmax(T& a,U b){if(a<b){a=b;return true;}return false;}
llint gcd(llint a,llint b){if(a%b==0){return b;}else return gcd(b,a%b);}
llint lcm(llint a,llint b){if(a==0){return b;}return a/gcd(a,b)*b;}
template<class T> void SO(T& ve){sort(ve.begin(),ve.end());}
template<class T> void REV(T& ve){reverse(ve.begin(),ve.end());}
template<class T>int LBI(const vector<T>&ar,T in){return lower_bound(ar.begin(),ar.end(),in)-ar.begin();}
template<class T>int UBI(const vector<T>&ar,T in){return upper_bound(ar.begin(),ar.end(),in)-ar.begin();}



int main(void){
	cout<<fixed<<setprecision(20);
	int n,m,h,i,j;double P;cin>>n>>m>>P;
	P/=100;
	int gra[14][14]={};
	for(i=0;i<m;i++){
		int u,v;cin>>u>>v;u--;v--;
		gra[u][v]=1;
		gra[v][u]=1;
	}
	int kai[15];
	kai[0]=1;
	for(i=1;i<=n;i++){kai[i]=kai[i-1]*3;}
	//3^14  0=未到達 1=到達可能 2=辺考慮済み
	static double dp[1594323]={};
	dp[0]=1.0;
	for(h=0;h<n;h++){
		for(i=n-1;i>=0;i--){
			if(i==n-1&&h>0){continue;}
			for(j=0;j<n-1;j++){
				if(!gra[i][j]){continue;}
				int bi=0;
				while(bi<kai[n-1]){
					if(i!=n-1){
						if(bi/kai[i]%3!=1){bi+=kai[i];continue;}
					}
					if(bi/kai[j]%3!=0){bi+=kai[j];continue;}
					dp[bi+kai[j]]+=dp[bi]*(1-P);
					dp[bi]*=P;
					bi++;
				}
			}
			if(i!=n-1){
				int bi=0;
				while(bi<kai[n-1]){
					if(bi/kai[i]%3!=1){bi+=kai[i];continue;}
					dp[bi+kai[i]]+=dp[bi];
					dp[bi]=0;
					bi++;
				}
			}
		}
	}
	
	cout<<dp[kai[n-1]-1]<<endl;
	return 0;
}
/*
12
*/
accuracy: 1
time_ms: 2980
memory_kb: 15956
final_rank: 18

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long;

int main() {
    cout << fixed << setprecision(15);

    int N, M, P;
    cin >> N >> M >> P;
    vector<pair<int, int>> edges;
    for (int i = 0; i < M; i++) {
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        edges.push_back({u, v});
    }

    double p = double(P) / 100;
    vector<double> dp(1 << N);

    for (int s_it = 0; s_it < 1 << (N - 1); s_it++) {
        int s = (s_it << 1) | 1;
        vector<pair<int, int>> s_cut_edges;
        int s_cut_count = 0;
        for (auto &&[u, v] : edges) {
            if (((s >> u) ^ (s >> v)) & 1) {
                s_cut_count++;
                s_cut_edges.push_back({u, v});
            }
        }
        dp[s] = pow(p, s_cut_count);
        int t_it = s_it;
        while (t_it > 0) {
            t_it--;
            t_it &= s_it;
            int t = (t_it << 1) | 1;
            int t_comp_cut_count = 0;
            for (auto &&[u, v] : s_cut_edges) {
                if ((((t >> u) & 1) == 0) && ((t >> v) & 1) == 0) {
                    t_comp_cut_count++;
                }
            }
            dp[s] -= dp[t] * pow(p, t_comp_cut_count);
            // cerr << s << ' ' << t << ' ' << dp[s] << endl;
            if (t == 1) {
                break;
            }
        }
        // cerr << s << ' ' << dp[s] << endl;
    }

    cout << dp[(1 << N) - 1] << endl;

    return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 4028
final_rank: 7